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 +23 -13
- package/icon.svg +76 -0
- package/package.json +7 -5
- package/stdlib/REVIEW_NEW_LIBS.md +92 -0
- package/stdlib/array.js +165 -0
- package/stdlib/array.kade +137 -0
- package/stdlib/async-helpers.js +115 -0
- package/stdlib/async.js +78 -0
- package/stdlib/async.kade +43 -0
- package/stdlib/check.js +8 -1
- package/stdlib/check.kade +7 -0
- package/stdlib/file.js +4 -4
- package/stdlib/file.kade +4 -2
- package/stdlib/format-helpers.js +51 -0
- package/stdlib/format.js +150 -0
- package/stdlib/format.kade +123 -0
- package/stdlib/list-helpers.js +21 -0
- package/stdlib/list-test.js +109 -0
- package/stdlib/list.js +9 -0
- package/stdlib/list.kade +10 -0
- package/stdlib/map.js +103 -0
- package/stdlib/map.kade +68 -0
- package/stdlib/network.js +8 -5
- package/stdlib/network.kade +10 -7
- package/stdlib/object-helpers.js +50 -1
- package/stdlib/random.js +1 -1
- package/stdlib/random.kade +1 -1
- package/stdlib/set.js +137 -0
- package/stdlib/set.kade +110 -0
- package/stdlib/test-reverse.kade +12 -0
- package/stdlib/test.js +28 -1
- package/stdlib/test.kade +27 -0
- package/stdlib/uuid.js +10 -10
- package/stdlib/uuid.kade +10 -10
- package/stdlib/validation-helpers.js +75 -0
- package/stdlib/validation.js +113 -0
- package/stdlib/validation.kade +78 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/kadence-lang)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
|
-
[](https://github.com/
|
|
5
|
+
[](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
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
| `
|
|
142
|
-
| `
|
|
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`
|
|
150
|
+
| `env` | `getEnv`, `hasEnv` |
|
|
145
151
|
| `process` | `args`, `exit`, `cwd` |
|
|
146
|
-
| `system` | `platform`, `arch`, `totalMemory`, `freeMemory` |
|
|
147
|
-
| `network` | `serve`, `fetchJson`
|
|
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` | `
|
|
152
|
-
| `html` | `div`, `span`, `p`, `img`, `link`
|
|
153
|
-
| `crypto` | `hash`, `randomBytes
|
|
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.
|
|
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/
|
|
12
|
+
"url": "git+https://github.com/Down2EarthGG/Kadence-lang.git"
|
|
12
13
|
},
|
|
13
14
|
"bugs": {
|
|
14
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "https://github.com/Down2EarthGG/Kadence-lang/issues"
|
|
15
16
|
},
|
|
16
|
-
"homepage": "https://github.com/
|
|
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.
|
package/stdlib/array.js
ADDED
|
@@ -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
|
+
}
|