slang-ts 0.2.0 → 0.2.2

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/CHANGELOG.md CHANGED
@@ -1,11 +1,10 @@
1
1
  # Changelog
2
2
 
3
- Everything notable in `slang-ts`, grouped by area. No release diary — just what's here.
3
+ Everything notable in `slang-ts`, grouped by area. No release diary: just what's here.
4
4
 
5
5
  ## Results and flow
6
6
 
7
- - `Ok(value, message?)` keeps an optional success message on the result, like text you want to show
8
- the user. Results without one have no `message` property.
7
+ - `Ok(value, message?)` keeps an optional success message on the result. Results without one have no `message` property.
9
8
  - `SafeTry` unwraps Option and Atom values into one result. A Result never nests inside another
10
9
  Result, and plain object properties and array elements stay unchanged.
11
10
 
package/README.md CHANGED
@@ -39,7 +39,7 @@ if (result.isOk) {
39
39
  }
40
40
  ```
41
41
 
42
- `println` is optional — it's a small development logger.
42
+ `println` is optional: it's a small development logger.
43
43
 
44
44
  ## Imports
45
45
 
@@ -107,7 +107,7 @@ import { option, Ok, Err, atom, match } from "slang-ts";
107
107
  - [println][logging] (with `setEnvironment`)
108
108
  - [createStepper][stepper]
109
109
 
110
- Full reference: [docs index][docs-index]. Feature list: [CHANGELOG.md][changelog].
110
+ Full reference: [docs index][docs-index]. Feature list: [CHANGELOG.md][changelog]. Agent guide: [skill/SKILL.md](skill/SKILL.md).
111
111
 
112
112
  ## Real-world examples
113
113
 
@@ -168,7 +168,7 @@ Full detail: [SafeTry][safe-try] and [Result][result].
168
168
  ### Call an API with a timeout and retries: SuperPromise
169
169
 
170
170
  Your function gets an `AbortSignal`. `timeout` aborts an attempt, `retry` runs it again after an
171
- ordinary failure, and you get back `Ok` or `Err` — so no `try`/`catch` around the await.
171
+ ordinary failure, and you get back `Ok` or `Err`: so no `try`/`catch` around the await.
172
172
 
173
173
  ```ts
174
174
  import { superPromise, println } from "slang-ts";
@@ -287,3 +287,4 @@ MIT License. See [LICENSE][license].
287
287
  [docs-index]: https://github.com/Hussseinkizz/slang/blob/main/docs/README.md
288
288
  [changelog]: https://github.com/Hussseinkizz/slang/blob/main/CHANGELOG.md
289
289
  [license]: https://github.com/Hussseinkizz/slang/blob/main/LICENSE
290
+ [skill]: https://github.com/Hussseinkizz/slang/blob/main/skill/SKILL.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slang-ts",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Functional programming utilities for TypeScript: Option, Result, SafeTry, pattern matching, async control, and data helpers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -15,6 +15,7 @@
15
15
  "types": "dist/index.d.ts",
16
16
  "files": [
17
17
  "dist",
18
+ "skill",
18
19
  "CHANGELOG.md"
19
20
  ],
20
21
  "engines": {
package/skill/SKILL.md ADDED
@@ -0,0 +1,190 @@
1
+ # slang-ts agent skill
2
+
3
+ This skill tells AI agents how to work with slang-ts: its APIs, patterns, and conventions so agents can write correct TypeScript against it.
4
+
5
+ ## What slang-ts is
6
+
7
+ slang-ts is a zero-dependency functional programming library for TypeScript. It brings Rust- and Erlang-style utilities: `Option`, `Result`, `SafeTry`, pattern matching (`match`/`matchAll`), async control (`SuperPromise`, `SuperRunner`, `taskGroup`, `Signal`, `Channel`), and data helpers (`list`, `struct`, `sets`, `Ok.iterate`, `memoized`, `zip`, `pipe`, `atom`, `to`).
8
+
9
+ Import only what you use:
10
+
11
+ ```ts
12
+ import { option, Ok, Err, match, superPromise, list } from "slang-ts";
13
+ ```
14
+
15
+ ## Core wrappers
16
+
17
+ ### Option
18
+
19
+ `option<T>(value): Option<T>` — wraps a value that may or may not be there.
20
+
21
+ `0` and `false` count as present; `null`, `undefined`, `""`, `NaN`, and `Infinity` are `None`.
22
+
23
+ ```ts
24
+ const port = option(process.env.PORT).unwrap().else(3000);
25
+ ```
26
+
27
+ Never read `.value` on `None`. Check `.isSome` / `.isNone` first, or use `.unwrap().else(fallback)`.
28
+
29
+ ### Result
30
+
31
+ `Result<T, E>` is `Ok<T>` or `Err<E>`.
32
+
33
+ ```ts
34
+ Ok<T>(value, message?); // success, optional message
35
+ Err<E>(error, raw?); // failure, optional diagnostic cause
36
+ ```
37
+
38
+ `Err(error, raw?)` keeps the original cause on the non-enumerable `.raw` for logs; `.error` stays human-readable.
39
+
40
+ Branch with `if (result.isOk) { ... } else { ... }`. Finish chains with `.unwrap().else(fallback)` or `.unwrap().panic(message?)`.
41
+
42
+ ```ts
43
+ function divide(a: number, b: number): Result<number, string> {
44
+ return b === 0 ? Err("Cannot divide by zero") : Ok(a / b);
45
+ }
46
+ ```
47
+
48
+ `Result` never nests inside another `Result` — `Ok(Ok(x))` and `Ok(Err(x))` won't compile.
49
+
50
+ ### match / matchAll
51
+
52
+ `match(value, patterns)` — exhaustive pattern matching for `Option` and `Result`. TypeScript requires both cases.
53
+
54
+ ```ts
55
+ match(result, { Ok: (v) => ..., Err: (e) => ... });
56
+ ```
57
+
58
+ `matchAll(value, patterns)` — matching for strings, numbers, booleans, symbols, and `Atom`s. Always needs a `_` fallback.
59
+
60
+ ```ts
61
+ const message = matchAll(failed.category, {
62
+ OUT_OF_BOUNDS: () => "That page is out of range.",
63
+ _: (category) => `Unexpected failure: ${category}`,
64
+ });
65
+ ```
66
+
67
+ ## Collection chains (list, struct, sets, Ok.iterate)
68
+
69
+ These return a `Fallible<T>`, not a plain `Result`. Finish with `.else(fallback)` or `.panic(message?)`. On failure, `.category` holds a string like `"OUT_OF_BOUNDS"` or `"INVALID_INPUT"`.
70
+
71
+ ```ts
72
+ const failed = list([1, 2, 3]).range(1, 99).take(1);
73
+ if (failed.category === "OUT_OF_BOUNDS") {
74
+ println(failed.else([])); // []
75
+ } else {
76
+ failed.panic(failed.category);
77
+ }
78
+ ```
79
+
80
+ - `get` already takes a fallback: `get(key, fallback)`. Do not pair `get(x, fallback)` with `.else(fallback)` — that's redundant.
81
+ - `.panic()` throws; once you panic, no custom message is read afterward.
82
+
83
+ ### list
84
+
85
+ `list<T>(input): ListChain<T>` — strict indexed arrays with explicit bounds. Out-of-range fails instead of clamping.
86
+
87
+ ```ts
88
+ const page = list(users).range(start, end).else([]);
89
+ ```
90
+
91
+ Methods: `get`, `take`, `skip`, `range`, `chunk`, `count`, `prune`.
92
+
93
+ ### struct
94
+
95
+ `struct<T>(input): StructChain<T>` — safe record access and shaping.
96
+
97
+ Methods: `get`, `pick`, `omit`, `merge`, `countBy`, `keyBy`, `prune`.
98
+
99
+ ```ts
100
+ const port = struct(config).get(["server", "port"], 3000);
101
+ ```
102
+
103
+ - `prune` drops Slang-falsy values (`null`, `undefined`, `""`, `NaN`, `Infinity`, `-Infinity`) but keeps `0` and `false`. Its predicate receives `(value, key)` and returns `true` to keep a value. It needs a plain object.
104
+ - Wrong shape for the operation fails with `INVALID_INPUT`. A missing `get` path fails with `OUT_OF_BOUNDS`. Once a chain fails, later steps don't run, and the category survives so you can check `.category`.
105
+
106
+ ### sets
107
+
108
+ `sets<T>(input): SetsChain<T>` — membership and set operations.
109
+
110
+ Methods: `has`, `unique`, `union`, `intersection`, `difference`. Objects compare by identity; primitives by value.
111
+
112
+ ### Ok.iterate
113
+
114
+ `Ok<T>(value).iterate(): IterateChain<T>` — lazy pipelines over a successful `Ok`.
115
+
116
+ Methods: `map`, `filter`, `flatMap`, `take`, `drop`, `chunk`, `reduce`, `count`, `toArray`.
117
+
118
+ ```ts
119
+ const names = Ok(users)
120
+ .iterate()
121
+ .filter((u) => u.active)
122
+ .map((u) => u.name)
123
+ .toArray()
124
+ .else([]);
125
+ ```
126
+
127
+ ## Async
128
+
129
+ ### SuperPromise
130
+
131
+ `superPromise<T>(fn, options?): SuperPromise<T>` — one async operation with start, retry, timeout, and cancel controls. Your function gets an `AbortSignal`. Tasks end as `Ok` or `Err`.
132
+
133
+ Options: `defer`, `delay`, `timeout`, `retry`, `retryUntil`, `group`.
134
+
135
+ ```ts
136
+ const user = await superPromise(
137
+ async (signal) => {
138
+ const response = await fetch(`/api/users/${id}`, { signal });
139
+ return response.json();
140
+ },
141
+ { timeout: 5000, retry: 2 },
142
+ );
143
+ ```
144
+
145
+ ### SuperRunner
146
+
147
+ `superRunner(config): SuperRunner<Value>` — manages several already-created `SuperPromise`s: sequence, parallel, or race. `start()` runs once.
148
+
149
+ ```ts
150
+ const all = superRunner({ type: "all", runners: { a, b } });
151
+ const result = await all.start();
152
+ ```
153
+
154
+ ### taskGroup
155
+
156
+ `taskGroup(name, options?): TaskGroup` — shared concurrency limit and start spacing across tasks and runners. Retries wait for a new slot.
157
+
158
+ ```ts
159
+ const api = taskGroup("user-api", { concurrency: 3, throttle: 200 });
160
+ const task = superPromise(fetchUsers, { group: api });
161
+ ```
162
+
163
+ ### Signal / Channel
164
+
165
+ `createSignal(): Signal` — a trigger that fires once (`fire()`), AbortSignal-compatible.
166
+
167
+ `createChannel(): Channel` — in-process publish/subscribe. `subscribe(topic, handler)` returns an unsubscribe function.
168
+
169
+ ## Other utilities
170
+
171
+ - `atom<T>(name): Atom<T>` — unique symbol with a readable description; matches in `matchAll` by description.
172
+ - `to(target)` — convert between `Option`, `Atom`, `Result` (e.g. `option("ready").to("atom")`).
173
+ - `pipe(value, ...fns)` — run `Result`-returning steps in order, stopping at the first failure.
174
+ - `zip` / `zipWith` / `unzip` — combine parallel collections.
175
+ - `memoized(fn)` — cache a function by argument identity.
176
+ - `panic(message)` — throw immediately for unrecoverable states.
177
+ - `println` — dev logging, silent in production unless `setEnvironment` routes it.
178
+
179
+ ## Conventions agents should follow
180
+
181
+ - Named params in an object for multi-arg functions, not positional.
182
+ - No classes: use functions and plain objects.
183
+ - Error categories are strings (`.category`), not numeric codes. Never call them "error codes."
184
+ - `get` accepts a fallback; don't chain `.else()` after a `get` that already has one.
185
+ - `.panic()` throws: only for unrecoverable states. Use `Result` / `.else()` for expected failures.
186
+ - Zero runtime dependencies; ESM only.
187
+
188
+ ## Package contents
189
+
190
+ The published package ships `dist/` (JS + bundled declarations), `CHANGELOG.md`, and `skill/SKILL.md` (this file, for agents working with slang-ts).