kadence-lang 0.2.0 → 0.2.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.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/kadence-lang.svg?style=flat-square)](https://www.npmjs.com/package/kadence-lang)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](https://opensource.org/licenses/MIT)
5
- [![Build Status](https://img.shields.io/badge/build-passing-brightgreen?style=flat-square)](https://github.com/kadence-lang/kadence-lang)
5
+ [![Build Status](https://img.shields.io/badge/build-passing-brightgreen?style=flat-square)](https://github.com/Down2EarthGG/Kadence-lang)
6
6
 
7
7
  **A human-readable programming language that feels like poetry.**
8
8
 
@@ -135,22 +135,32 @@ Kadence ships with a comprehensive set of modules for common tasks.
135
135
 
136
136
  | Module | Core Functionality |
137
137
  | :--- | :--- |
138
- | `list` | `first`, `lastOf`, `shuffle`, `range`, `unique` |
139
- | `string` | `trimmed`, `repeated`, `toCamelCase`, `padStart`, `words` |
140
- | `math` | `clamp`, `randomFloat`, `toRadians`, `hypotenuse` |
141
- | `datetime` | `the time now`, `the date today`, `diffDays`, `toIso` |
142
- | `file` | `readFile`, `writeFile`, `copyDir`, `removeDir`, `stat` |
138
+ | `array` | `flatten`, `zip`, `chunk`, `partition`, `take`, `drop`, `reverse`, `findIndex` |
139
+ | `async` | `delay`, `timeout`, `retry`, `debounce`, `throttle`, `parallel`, `sequential`, `waterfall` |
140
+ | `list` | `first`, `lastOf`, `shuffle`, `makeRange`, `unique`, `sort`, `sortBy` |
141
+ | `string` | `trimmed`, `repeated`, `toCamelCase`, `padStart`, `words`, `lines`, `capitalized` |
142
+ | `map` | `keys`, `values`, `entries`, `merge`, `pick`, `omit`, `mapValues`, `deepClone`, `fromPairs` |
143
+ | `set` | `union`, `intersection`, `difference`, `isSubset`, `isSuperset`, `cartesianProduct` |
144
+ | `format` | `currency`, `fileSize`, `ordinal`, `plural`, `titleCase`, `snakeCase`, `kebabCase` |
145
+ | `validation` | `isEmail`, `isUrl`, `isNumeric`, `isAlpha`, `isInRange`, `isHexColor`, `isCreditCard` |
146
+ | `math` | `clamp`, `randomFloat`, `hypotenuse`, `areaOfCircle`, `isEven`, `toRadians` |
147
+ | `datetime` | `currentTime`, `today`, `year`, `month`, `day`, `toIso`, `addDays` |
148
+ | `file` | `readFile`, `writeFile`, `copyDir`, `removeDir`, `stat`, `listDir`, `exists` |
143
149
  | `path` | `joinPaths`, `resolve`, `basename`, `dirname`, `extension` |
144
- | `env` | `getEnv`, `hasEnv` (Environment Variables) |
150
+ | `env` | `getEnv`, `hasEnv` |
145
151
  | `process` | `args`, `exit`, `cwd` |
146
- | `system` | `platform`, `arch`, `totalMemory`, `freeMemory` |
147
- | `network` | `serve`, `fetchJson` (Simple HTTP Server) |
152
+ | `system` | `platform`, `arch`, `totalMemory`, `freeMemory`, `cpus`, `homedir` |
153
+ | `network` | `serve`, `fetchJson` |
148
154
  | `json` | `readJson`, `writeJson`, `format`, `parseSafe` |
149
- | `check` | `isNumber`, `isString`, `isEmail`, `between` |
155
+ | `check` | `isNumber`, `isString`, `isEmail`, `between`, `coalesce` |
150
156
  | `test` | `suite`, `assertEquals`, `assertTrue`, `assertThrows` |
151
- | `color` | `randomHex`, `rgbToHex`, `hexToRgb` |
152
- | `html` | `div`, `span`, `p`, `img`, `link` (Browser only) |
153
- | `crypto` | `hash`, `randomBytes`, `uuid` |
157
+ | `color` | `rgb`, `rgba`, `hex`, `randomHex` |
158
+ | `html` | `tag`, `div`, `span`, `p`, `img`, `link`, `h1` |
159
+ | `crypto` | `hash`, `randomBytes` |
160
+ | `uuid` | `v4`, `validate` |
161
+ | `random` | `float`, `integer`, `choice`, `shuffle` |
162
+ | `stream` | `createReader`, `readAll`, `pipe` |
163
+ | `url` | `parseUrl`, `buildUrl`, `getSearchParam` |
154
164
 
155
165
  *Usage Example:*
156
166
  ```kadence
package/icon.svg ADDED
@@ -0,0 +1,76 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg width="512" height="512" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg">
3
+ <defs>
4
+ <!-- Premium Dark Gradient Background -->
5
+ <linearGradient id="bgGradient" x1="0%" y1="0%" x2="100%" y2="100%">
6
+ <stop offset="0%" style="stop-color:#1a1a2e;stop-opacity:1" />
7
+ <stop offset="100%" style="stop-color:#16213e;stop-opacity:1" />
8
+ </linearGradient>
9
+
10
+ <!-- Vibrant Accent Gradient (vertical) -->
11
+ <linearGradient id="accentGradient" x1="0%" y1="0%" x2="0%" y2="100%">
12
+ <stop offset="0%" style="stop-color:#06d6a0;stop-opacity:1" />
13
+ <stop offset="50%" style="stop-color:#118ab2;stop-opacity:1" />
14
+ <stop offset="100%" style="stop-color:#7b2cbf;stop-opacity:1" />
15
+ </linearGradient>
16
+
17
+ <!-- Outer Glow Effect -->
18
+ <filter id="glow" x="-50%" y="-50%" width="200%" height="200%">
19
+ <feGaussianBlur stdDeviation="6" result="coloredBlur"/>
20
+ <feMerge>
21
+ <feMergeNode in="coloredBlur"/>
22
+ <feMergeNode in="SourceGraphic"/>
23
+ </feMerge>
24
+ </filter>
25
+
26
+ <!-- Subtle Drop Shadow -->
27
+ <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
28
+ <feDropShadow dx="0" dy="4" stdDeviation="10" flood-color="#000000" flood-opacity="0.3"/>
29
+ </filter>
30
+ </defs>
31
+
32
+ <!-- Background Container with Rounded Corners -->
33
+ <rect x="24" y="24" width="464" height="464" rx="96" fill="url(#bgGradient)" filter="url(#shadow)"/>
34
+
35
+ <!-- Subtle Border Ring -->
36
+ <rect x="24" y="24" width="464" height="464" rx="96" fill="none" stroke="url(#accentGradient)" stroke-width="3" opacity="0.4"/>
37
+
38
+ <!-- Rebuilt, unified Kadence "K" -->
39
+ <g filter="url(#glow)">
40
+ <!-- Single sculpted K shape using negative space logic -->
41
+ <path
42
+ d="
43
+ M 120 116
44
+ L 160 116
45
+ L 160 220
46
+ L 230 160
47
+ Q 244 148 262 148
48
+ L 292 148
49
+ L 292 188
50
+ Q 276 188 266 196
51
+ L 200 252
52
+ L 270 320
53
+ Q 284 334 304 334
54
+ L 332 334
55
+ L 332 374
56
+ L 296 374
57
+ Q 270 374 252 356
58
+ L 180 286
59
+ L 160 304
60
+ L 160 396
61
+ L 120 396
62
+ Z
63
+ "
64
+ fill="url(#accentGradient)"
65
+ />
66
+
67
+ <!-- Accent rhythm bars to the right -->
68
+ <rect x="320" y="196" width="24" height="120" rx="12" fill="#06d6a0" opacity="0.9"/>
69
+ <rect x="360" y="161" width="24" height="190" rx="12" fill="#118ab2" opacity="0.85"/>
70
+ <rect x="400" y="216" width="24" height="80" rx="12" fill="#7b2cbf" opacity="0.8"/>
71
+ </g>
72
+
73
+ <!-- Small accent dots for visual interest -->
74
+ <circle cx="420" cy="100" r="8" fill="#06d6a0" opacity="0.6"/>
75
+ <circle cx="100" cy="420" r="6" fill="#7b2cbf" opacity="0.5"/>
76
+ </svg>
package/package.json CHANGED
@@ -1,25 +1,27 @@
1
1
  {
2
2
  "name": "kadence-lang",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "A human-readable programming language that feels like poetry",
5
+ "icon": "icon.svg",
5
6
  "main": "src/compiler.js",
6
7
  "bin": {
7
8
  "kadence": "./bin/kadence.js"
8
9
  },
9
10
  "repository": {
10
11
  "type": "git",
11
- "url": "git+https://github.com/kadence-lang/kadence-lang.git"
12
+ "url": "git+https://github.com/Down2EarthGG/Kadence-lang.git"
12
13
  },
13
14
  "bugs": {
14
- "url": "https://github.com/kadence-lang/kadence-lang/issues"
15
+ "url": "https://github.com/Down2EarthGG/Kadence-lang/issues"
15
16
  },
16
- "homepage": "https://github.com/kadence-lang/kadence-lang#readme",
17
+ "homepage": "https://github.com/Down2EarthGG/Kadence-lang#readme",
17
18
  "files": [
18
19
  "src/",
19
20
  "bin/",
20
21
  "stdlib/",
21
22
  "README.md",
22
- "LICENSE"
23
+ "LICENSE",
24
+ "icon.svg"
23
25
  ],
24
26
  "engines": {
25
27
  "node": ">=14.0.0"
@@ -0,0 +1,92 @@
1
+ # Review: New stdlib Libraries
2
+
3
+ Summary of the new/untracked stdlib modules and fixes applied.
4
+
5
+ ---
6
+
7
+ ## 1. **array.kade** ✓
8
+
9
+ Pure Kadence array utilities: `flatten`, `zip`, `chunk`, `partition`, `take`, `drop`, `reverse`, `findIndex`.
10
+
11
+ - **Style**: Uses `list`, `add … to result`, `size of`, `increment`/`decrement` consistently.
12
+ - **Note**: `flatten` treats any `elem` with `typeof "object"` and `elem.length` as nested array; that matches array-like values. Consider documenting that only one level of “array-like” is assumed if you want to avoid surprises with non-Array objects.
13
+
14
+ ---
15
+
16
+ ## 2. **async.kade** + **async-helpers.js** ✓
17
+
18
+ Kadence wrapper over JS helpers: `delay`, `timeout`, `retry`, `debounce`, `throttle`, `parallel`, `race`, `sequential`, `waterfall`, `batch`.
19
+
20
+ - **Pattern**: Same as other `.kade` + `-helpers.js` pairs: Kadence exports call `run require "./async-helpers.js"` and `run mod.<name> …`.
21
+ - **async-helpers.js**: Clear, no extra dependencies; `batch` expects `processFn(batchItems)` to return an array of results.
22
+ - **async.js**: Generated output; contains leftover `__kadence_*` and `fs` at the top. Prefer regenerating from `async.kade` or trimming the stub so only the actual exports remain.
23
+
24
+ ---
25
+
26
+ ## 3. **format.kade** + **format-helpers.js** ✓ (ordinal fixed)
27
+
28
+ Formatting: `currency`, `formatNumber`, `percentage`, `fileSize`, `ordinal`, `plural`, `truncate`, `ellipsis`, `padNumber`, `phoneNumber`, `titleCase`, `snakeCase`, `kebabCase`.
29
+
30
+ - **ordinal**: Logic was wrong for both remainder and 11/12/13. Updated to use `floor` for integer-like behavior and to treat 11–13 correctly (e.g. 11th, 12th, 13th, 21st, 22nd).
31
+ - **format-helpers.js**: Only `currency` and `phoneNumber`; used via `require`. Fine as-is.
32
+ - **titleCase**: Uses `split`/`join`/`uppercase`/`lowercase`; consistent with language reference.
33
+
34
+ ---
35
+
36
+ ## 4. **map.kade** + **map.js** + **object-helpers.js** ✓
37
+
38
+ Map/object utilities: `keys`, `values`, `entries`, `hasKey`, `merge`, `pick`, `omit`, `mapValues`, `mapKeys`, `invert`, `isEmpty`, `fromPairs`.
39
+
40
+ - **map.kade**: Delegates to `object-helpers.js` for everything except `isEmpty` (uses `Object.keys`) and `fromPairs` (inline loop). Good split.
41
+ - **object-helpers.js**: Provides `pick`, `omit`, `deepClone`, `get`, `defaults`, plus key/values/entries/hasKey/merge/mapValues/mapKeys/invert. `map.kade` does not yet expose `deepClone`, `get`, or `defaults`; add wrappers in `map.kade` if you want them in the public API.
42
+ - **fromPairs**: Uses `let result = {}` and `result[pair[0]] = pair[1]`. For consistency with LANGUAGE_REFERENCE (“Object: object { key: val }”), you could use `object {}` and `set … of result to …` if the compiler supports empty `object {}` and property set.
43
+
44
+ ---
45
+
46
+ ## 5. **set.kade** ✓
47
+
48
+ Set operations on lists (no native Set): `union`, `intersection`, `difference`, `symmetricDifference`, `isSubset`, `isSuperset`, `areDisjoint`, `cartesianProduct`.
49
+
50
+ - **Style**: Pure Kadence, no JS helpers; uses nested `for each` and equality. Readable.
51
+ - **Cost**: O(n²) in many places (e.g. membership via linear search). Acceptable for small sets; for large sets consider a JS helper backed by `Set` and call it from a thin `.kade` wrapper (like async/format).
52
+
53
+ ---
54
+
55
+ ## 6. **validation.kade** ✓ (comparisons fixed)
56
+
57
+ Validators: `isEmail`, `isUrl`, `isNumeric`, `isAlpha`, `isAlphanumeric`, `isInteger`, `isPositive`, `isNegative`, `isInRange`, `isLength`, `isEmpty`/`isNotEmpty`, `isHexColor`, `isIpAddress`, `isPhoneNumber`, `isCreditCard` (Luhn), `isStrongPassword`.
58
+
59
+ - **Comparisons**: The compiler only supports `at least` / `at most` for ≥/≤ (see `CompareOp` in grammar). Replaced “more than or equals” / “less than or equals” with “at least” / “at most” in `isInRange`, `isLength`, `isPhoneNumber`, and the Luhn loop.
60
+ - **Name clash**: Resolved by renaming string “blank” check from `isEmpty` to `isBlank`; `isNotEmpty` now calls `isBlank`.
61
+ - **Luhn**: Logic for `isCreditCard` is correct; `(sum / 10) * 10 equals sum` is a valid way to express “sum divisible by 10” without a mod operator.
62
+
63
+ ---
64
+
65
+ ## 7. **object-helpers.js** (modified)
66
+
67
+ Shared implementation for object/map operations. Used by **map.kade**; no issues found. Exports are consistent with what **map.kade** calls.
68
+
69
+ ---
70
+
71
+ ## 8. **.object.kade.js**
72
+
73
+ Appears to be compiled output (e.g. from a file like `object.kade`). Typically such files are generated; consider adding them to `.gitignore` or generating them in a build step so they aren’t committed as source.
74
+
75
+ ---
76
+
77
+ ## Summary of changes made
78
+
79
+ | File | Change |
80
+ |------------------|------------------------------------------------------------------------|
81
+ | **validation.kade** | Replaced “more than or equals” / “less than or equals” with “at least” / “at most” in four places so the code parses and runs. |
82
+ | **format.kade** | Reworked `ordinal` to use `floor` for tens/remainder and to handle 11–13 correctly (e.g. 11th, 21st). |
83
+
84
+ ---
85
+
86
+ ## Recommendations (implemented)
87
+
88
+ 1. **Consistency**: Use “at least” / “at most” everywhere; **validation.kade** and **test-reverse.kade** were updated.
89
+ 2. **validation.kade** `isEmpty`: Renamed to `isBlank`; `isNotEmpty` now calls `isBlank`.
90
+ 3. **map.kade**: Exposes `deepClone`, `get`, and `defaults` from **object-helpers.js**; **map.js** updated to match.
91
+ 4. **async.js / map.js**: Removed `__kadence_*` and `fs` stubs so the emitted JS is minimal.
92
+ 5. **.object.kade.js**: Added `stdlib/.object.kade.js` to **.gitignore** so generated output is not committed.
@@ -0,0 +1,165 @@
1
+ const fs = require("fs");
2
+
3
+ function __kadence_echo(val) {
4
+ const s = String(val);
5
+ const low = s.toLowerCase();
6
+ if (typeof process !== 'undefined' && process.stdout && process.stdout.isTTY) {
7
+ if (low.includes('error')) console.log("\x1b[31m" + s + "\x1b[0m");
8
+ else if (low.includes('warning')) console.log("\x1b[33m" + s + "\x1b[0m");
9
+ else if (low.includes('success')) console.log("\x1b[32m" + s + "\x1b[0m");
10
+ else console.log(s);
11
+ } else {
12
+ console.log(s);
13
+ }
14
+ }
15
+ function __kadence_min(val) {
16
+ if (Array.isArray(val)) return Math.min(...val);
17
+ return val;
18
+ }
19
+ function __kadence_max(val) {
20
+ if (Array.isArray(val)) return Math.max(...val);
21
+ return val;
22
+ }
23
+ function __kadence_add(parent, child) {
24
+ if (Array.isArray(parent)) {
25
+ parent.push(child);
26
+ return parent;
27
+ }
28
+ if (typeof parent === 'object' && parent !== null && typeof parent.appendChild === 'function') {
29
+ parent.appendChild(child);
30
+ return parent;
31
+ }
32
+ throw new Error("Runtime Error: Cannot add item to " + typeof parent);
33
+ }
34
+
35
+ function flatten (nestedArray) {
36
+ let result = [];
37
+ for (let elem of nestedArray) {
38
+ if (typeof elem === `object` && elem.length ) {
39
+ let flattened = flatten(elem);
40
+ for (let subItem of flattened) {
41
+ __kadence_add(result, subItem);
42
+ }
43
+ } else {
44
+ __kadence_add(result, elem);
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+ if (typeof exports !== 'undefined') exports.flatten = flatten;
50
+ function zip (array1, array2) {
51
+ let result = [];
52
+ let len1 = array1.length;
53
+ let len2 = array2.length;
54
+ let minLen = 0;
55
+ if (len1 < len2 ) {
56
+ minLen = len1;
57
+ } else {
58
+ minLen = len2;
59
+ }
60
+ let i = 0;
61
+ while (i < minLen ) {
62
+ let pair = [];
63
+ __kadence_add(pair, array1[i]);
64
+ __kadence_add(pair, array2[i]);
65
+ __kadence_add(result, pair);
66
+ i++;
67
+ }
68
+ return result;
69
+ }
70
+ if (typeof exports !== 'undefined') exports.zip = zip;
71
+ function chunk (array, chunkSize) {
72
+ let result = [];
73
+ let i = 0;
74
+ let len = array.length;
75
+ while (i < len ) {
76
+ let currentChunk = [];
77
+ let j = 0;
78
+ while (j < chunkSize && (i + j ) < len ) {
79
+ __kadence_add(currentChunk, array[i + j ]);
80
+ j++;
81
+ }
82
+ __kadence_add(result, currentChunk);
83
+ i = i + chunkSize ;
84
+ }
85
+ return result;
86
+ }
87
+ if (typeof exports !== 'undefined') exports.chunk = chunk;
88
+ function partition (array, predicate) {
89
+ let truthy = [];
90
+ let falsy = [];
91
+ for (let elem of array) {
92
+ if (predicate(elem)) {
93
+ __kadence_add(truthy, elem);
94
+ } else {
95
+ __kadence_add(falsy, elem);
96
+ }
97
+ }
98
+ let output = [];
99
+ __kadence_add(output, truthy);
100
+ __kadence_add(output, falsy);
101
+ return output;
102
+ }
103
+ if (typeof exports !== 'undefined') exports.partition = partition;
104
+ function take (array, count) {
105
+ let result = [];
106
+ let len = array.length;
107
+ let actualCount = 0;
108
+ if (count < len ) {
109
+ actualCount = count;
110
+ } else {
111
+ actualCount = len;
112
+ }
113
+ let i = 0;
114
+ while (i < actualCount ) {
115
+ __kadence_add(result, array[i]);
116
+ i++;
117
+ }
118
+ return result;
119
+ }
120
+ if (typeof exports !== 'undefined') exports.take = take;
121
+ function drop (array, count) {
122
+ let result = [];
123
+ let len = array.length;
124
+ let i = count;
125
+ while (i < len ) {
126
+ __kadence_add(result, array[i]);
127
+ i++;
128
+ }
129
+ return result;
130
+ }
131
+ if (typeof exports !== 'undefined') exports.drop = drop;
132
+ function reverse (array) {
133
+ let result = [];
134
+ let i = (array.length) - 1 ;
135
+ while (i >= 0 ) {
136
+ __kadence_add(result, array[i]);
137
+ i--;
138
+ }
139
+ return result;
140
+ }
141
+ if (typeof exports !== 'undefined') exports.reverse = reverse;
142
+ function findIndex (array, predicate) {
143
+ let i = 0;
144
+ let len = array.length;
145
+ while (i < len ) {
146
+ let elem = array[i];
147
+ if (predicate(elem)) {
148
+ return i;
149
+ }
150
+ i++;
151
+ }
152
+ return 0 - 1 ;
153
+ }
154
+ if (typeof exports !== 'undefined') exports.findIndex = findIndex;
155
+ function findFirst (array, predicate) {
156
+ let idx = findIndex(array, predicate);
157
+ if (idx >= 0 ) {
158
+ return array[idx];
159
+ }
160
+ return undefined;
161
+ }
162
+ if (typeof exports !== 'undefined') exports.findFirst = findFirst;
163
+ (async () => {
164
+
165
+ })().catch(err => { if (err) console.error("\x1b[31mRuntime Error:\x1b[0m", err.stack || err.message); });
@@ -0,0 +1,137 @@
1
+ note: Advanced array utilities for Kadence
2
+
3
+ export function flatten nestedArray
4
+ let result = list
5
+ for each elem in nestedArray
6
+ if typeof elem equals "object" and elem.length
7
+ let flattened = run flatten elem
8
+ for each subItem in flattened
9
+ add subItem to result
10
+ end
11
+ else
12
+ add elem to result
13
+ end
14
+ end
15
+ return result
16
+ end
17
+
18
+ export function zip array1 array2
19
+ let result = list
20
+ let len1 = size of array1
21
+ let len2 = size of array2
22
+ let minLen = 0
23
+ if len1 less than len2
24
+ set minLen to len1
25
+ else
26
+ set minLen to len2
27
+ end
28
+
29
+ let i = 0
30
+ while i less than minLen
31
+ let pair = list
32
+ add array1[i] to pair
33
+ add array2[i] to pair
34
+ add pair to result
35
+ increment i
36
+ end
37
+ return result
38
+ end
39
+
40
+ export function chunk array chunkSize
41
+ let result = list
42
+ let i = 0
43
+ let len = size of array
44
+
45
+ while i less than len
46
+ let currentChunk = list
47
+ let j = 0
48
+ while j less than chunkSize and (i plus j) less than len
49
+ add array[i plus j] to currentChunk
50
+ increment j
51
+ end
52
+ add currentChunk to result
53
+ set i to i plus chunkSize
54
+ end
55
+ return result
56
+ end
57
+
58
+ export function partition array predicate
59
+ let truthy = list
60
+ let falsy = list
61
+
62
+ for each elem in array
63
+ if run predicate elem
64
+ add elem to truthy
65
+ else
66
+ add elem to falsy
67
+ end
68
+ end
69
+
70
+ let output = list
71
+ add truthy to output
72
+ add falsy to output
73
+ return output
74
+ end
75
+
76
+ export function take array count
77
+ let result = list
78
+ let len = size of array
79
+ let actualCount = 0
80
+ if count less than len
81
+ set actualCount to count
82
+ else
83
+ set actualCount to len
84
+ end
85
+
86
+ let i = 0
87
+ while i less than actualCount
88
+ add array[i] to result
89
+ increment i
90
+ end
91
+ return result
92
+ end
93
+
94
+ export function drop array count
95
+ let result = list
96
+ let len = size of array
97
+ let i = count
98
+
99
+ while i less than len
100
+ add array[i] to result
101
+ increment i
102
+ end
103
+ return result
104
+ end
105
+
106
+ export function reverse array
107
+ let result = list
108
+ let i = (size of array) minus 1
109
+
110
+ while i at least 0
111
+ add array[i] to result
112
+ decrement i
113
+ end
114
+ return result
115
+ end
116
+
117
+ export function findIndex array predicate
118
+ let i = 0
119
+ let len = size of array
120
+
121
+ while i less than len
122
+ let elem = array[i]
123
+ if run predicate elem
124
+ return i
125
+ end
126
+ increment i
127
+ end
128
+ return 0 minus 1
129
+ end
130
+
131
+ export function findFirst array predicate
132
+ let idx = run findIndex array predicate
133
+ if idx at least 0
134
+ return array[idx]
135
+ end
136
+ return undefined
137
+ end
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+
3
+ function delay(milliseconds) {
4
+ return new Promise((resolve) => {
5
+ setTimeout(resolve, milliseconds);
6
+ });
7
+ }
8
+
9
+ function timeout(promise, milliseconds) {
10
+ const timeoutPromise = new Promise((_, reject) => {
11
+ setTimeout(() => {
12
+ reject(new Error("Operation timed out"));
13
+ }, milliseconds);
14
+ });
15
+
16
+ return Promise.race([promise, timeoutPromise]);
17
+ }
18
+
19
+ async function retry(fn, maxAttempts, delayMs) {
20
+ let attempt = 0;
21
+
22
+ while (attempt < maxAttempts) {
23
+ try {
24
+ const result = await fn();
25
+ return result;
26
+ } catch (error) {
27
+ attempt++;
28
+ if (attempt < maxAttempts) {
29
+ await new Promise(resolve => setTimeout(resolve, delayMs));
30
+ } else {
31
+ throw error;
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ function debounce(fn, delayMs) {
38
+ let timeoutId = null;
39
+
40
+ return function (...args) {
41
+ if (timeoutId) {
42
+ clearTimeout(timeoutId);
43
+ }
44
+
45
+ timeoutId = setTimeout(() => {
46
+ fn(...args);
47
+ }, delayMs);
48
+ };
49
+ }
50
+
51
+ function throttle(fn, delayMs) {
52
+ let lastRun = 0;
53
+
54
+ return function (...args) {
55
+ const now = Date.now();
56
+
57
+ if (now - lastRun >= delayMs) {
58
+ fn(...args);
59
+ lastRun = now;
60
+ }
61
+ };
62
+ }
63
+
64
+ async function sequential(tasks) {
65
+ const results = [];
66
+
67
+ for (const task of tasks) {
68
+ const result = await task();
69
+ results.push(result);
70
+ }
71
+
72
+ return results;
73
+ }
74
+
75
+ async function waterfall(tasks, initialValue) {
76
+ let value = initialValue;
77
+
78
+ for (const task of tasks) {
79
+ value = await task(value);
80
+ }
81
+
82
+ return value;
83
+ }
84
+
85
+ async function batch(items, batchSize, processFn) {
86
+ const results = [];
87
+ let i = 0;
88
+ const len = items.length;
89
+
90
+ while (i < len) {
91
+ const batchItems = [];
92
+ let j = 0;
93
+
94
+ while (j < batchSize && (i + j) < len) {
95
+ batchItems.push(items[i + j]);
96
+ j++;
97
+ }
98
+
99
+ const batchResults = await processFn(batchItems);
100
+ for (const result of batchResults) {
101
+ results.push(result);
102
+ }
103
+
104
+ i += batchSize;
105
+ }
106
+
107
+ return results;
108
+ }
109
+
110
+ if (typeof module !== "undefined" && module.exports) {
111
+ module.exports = {
112
+ delay, timeout, retry, debounce, throttle,
113
+ sequential, waterfall, batch
114
+ };
115
+ }