starlight-cli 1.1.5 → 1.1.6

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
@@ -224,6 +224,147 @@ This makes Starlight useful not only as a programming language, but also as a **
224
224
 
225
225
  ---
226
226
 
227
+ ## Array Helpers: map, filter, reduce
228
+
229
+ Starlight provides built-in **functional helpers** for working with arrays: `map`, `filter`, and `reduce`.
230
+ These helpers are **async-aware**, work seamlessly with **arrow functions**, and integrate fully with Starlight’s runtime and error handling.
231
+
232
+ Unlike JavaScript, these are **global functions** (not methods), keeping the language simple and consistent.
233
+
234
+ ---
235
+
236
+ ### map(array, fn)
237
+
238
+ Transforms each element of an array using a callback function and returns a **new array**.
239
+
240
+ **Syntax:**
241
+ ```
242
+
243
+ map(array, fn)
244
+
245
+ ```
246
+
247
+ **Example:**
248
+ ```
249
+
250
+ let numbers = [1, 2, 3, 4]
251
+
252
+ let squared = await map(numbers, x => x * x)
253
+
254
+ sldeploy squared
255
+
256
+ ```
257
+
258
+ **Output:**
259
+ ```
260
+
261
+ [ 1, 4, 9, 16 ]
262
+
263
+ ```
264
+
265
+ - `fn` receives `(value, index, array)`
266
+ - Does **not** modify the original array
267
+ - Supports `async` arrow functions
268
+
269
+ ---
270
+
271
+ ### filter(array, fn)
272
+
273
+ Selects elements from an array that satisfy a condition and returns a **new array**.
274
+
275
+ **Syntax:**
276
+ ```
277
+
278
+ filter(array, fn)
279
+
280
+ ```
281
+
282
+ **Example:**
283
+ ```
284
+
285
+ let numbers = [1, 2, 3, 4, 5, 6]
286
+
287
+ let evens = await filter(numbers, x => x % 2 == 0)
288
+
289
+ sldeploy evens
290
+
291
+ ```
292
+
293
+ **Output:**
294
+ ```
295
+
296
+ [ 2, 4, 6 ]
297
+
298
+ ```
299
+
300
+ - `fn` must return `true` or `false`
301
+ - `fn` receives `(value, index, array)`
302
+ - Original array remains unchanged
303
+
304
+ ---
305
+
306
+ ### reduce(array, fn, initial)
307
+
308
+ Reduces an array to a **single value** by accumulating results using a reducer function.
309
+
310
+ **Syntax:**
311
+ ```
312
+
313
+ reduce(array, fn, initial)
314
+
315
+ ```
316
+
317
+ **Example:**
318
+ ```
319
+
320
+ let numbers = [1, 2, 3, 4, 5]
321
+
322
+ let total = await reduce(numbers, (acc, value) => acc + value, 0)
323
+
324
+ sldeploy total
325
+
326
+ ```
327
+
328
+ **Output:**
329
+ ```
330
+
331
+ 15
332
+
333
+ ```
334
+
335
+ - `fn` receives `(accumulator, value, index, array)`
336
+ - `initial` is optional, but recommended
337
+ - Throws a runtime error if used on an empty array without an initial value
338
+
339
+ ---
340
+
341
+ ### Async Support
342
+
343
+ All three helpers support `async` functions:
344
+
345
+ ```
346
+
347
+ let results = await map(items, async item => {
348
+ await sleep(100)
349
+ return item * 2
350
+ })
351
+
352
+ ```
353
+
354
+ ---
355
+
356
+ ### Why global helpers?
357
+
358
+ Starlight keeps `map`, `filter`, and `reduce` as **language-level utilities** instead of object methods to:
359
+
360
+ - Keep syntax minimal and readable
361
+ - Avoid prototype complexity
362
+ - Work consistently with all iterables
363
+ - Integrate cleanly with the evaluator and runtime
364
+
365
+ ---
366
+
367
+
227
368
  ## Why Starlight?
228
369
 
229
370
  * A **simple but powerful** scripting language
package/dist/index.js CHANGED
@@ -10376,6 +10376,64 @@ formatValue(value, seen = new Set()) {
10376
10376
  if (Array.isArray(arg)) return 'array';
10377
10377
  return typeof arg;
10378
10378
  });
10379
+ this.global.define('map', async (array, fn) => {
10380
+ if (!Array.isArray(array)) {
10381
+ throw new RuntimeError('map() expects an array', null, this.source);
10382
+ }
10383
+ if (typeof fn !== 'function') {
10384
+ throw new RuntimeError('map() expects a function', null, this.source);
10385
+ }
10386
+
10387
+ const result = [];
10388
+ for (let i = 0; i < array.length; i++) {
10389
+ result.push(await fn(array[i], i, array));
10390
+ }
10391
+ return result;
10392
+ });
10393
+ this.global.define('filter', async (array, fn) => {
10394
+ if (!Array.isArray(array)) {
10395
+ throw new RuntimeError('filter() expects an array', null, this.source);
10396
+ }
10397
+ if (typeof fn !== 'function') {
10398
+ throw new RuntimeError('filter() expects a function', null, this.source);
10399
+ }
10400
+
10401
+ const result = [];
10402
+ for (let i = 0; i < array.length; i++) {
10403
+ if (await fn(array[i], i, array)) {
10404
+ result.push(array[i]);
10405
+ }
10406
+ }
10407
+ return result;
10408
+ });
10409
+ this.global.define('reduce', async (array, fn, initial) => {
10410
+ if (!Array.isArray(array)) {
10411
+ throw new RuntimeError('reduce() expects an array', null, this.source);
10412
+ }
10413
+ if (typeof fn !== 'function') {
10414
+ throw new RuntimeError('reduce() expects a function', null, this.source);
10415
+ }
10416
+
10417
+ let acc;
10418
+ let startIndex = 0;
10419
+
10420
+ if (initial !== undefined) {
10421
+ acc = initial;
10422
+ } else {
10423
+ if (array.length === 0) {
10424
+ throw new RuntimeError('reduce() of empty array with no initial value', null, this.source);
10425
+ }
10426
+ acc = array[0];
10427
+ startIndex = 1;
10428
+ }
10429
+
10430
+ for (let i = startIndex; i < array.length; i++) {
10431
+ acc = await fn(acc, array[i], i, array);
10432
+ }
10433
+
10434
+ return acc;
10435
+ });
10436
+
10379
10437
  this.global.define('keys', arg => arg && typeof arg === 'object' ? Object.keys(arg) : []);
10380
10438
  this.global.define('values', arg => arg && typeof arg === 'object' ? Object.values(arg) : []);
10381
10439
  this.global.define('range', (...args) => {
@@ -12409,7 +12467,7 @@ const Lexer = __nccwpck_require__(211);
12409
12467
  const Parser = __nccwpck_require__(222);
12410
12468
  const Evaluator = __nccwpck_require__(112);
12411
12469
 
12412
- const VERSION = '1.1.5';
12470
+ const VERSION = '1.1.6';
12413
12471
 
12414
12472
  const COLOR = {
12415
12473
  reset: '\x1b[0m',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "starlight-cli",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "Starlight Programming Language CLI",
5
5
  "bin": {
6
6
  "starlight": "index.js"
package/src/evaluator.js CHANGED
@@ -166,6 +166,64 @@ formatValue(value, seen = new Set()) {
166
166
  if (Array.isArray(arg)) return 'array';
167
167
  return typeof arg;
168
168
  });
169
+ this.global.define('map', async (array, fn) => {
170
+ if (!Array.isArray(array)) {
171
+ throw new RuntimeError('map() expects an array', null, this.source);
172
+ }
173
+ if (typeof fn !== 'function') {
174
+ throw new RuntimeError('map() expects a function', null, this.source);
175
+ }
176
+
177
+ const result = [];
178
+ for (let i = 0; i < array.length; i++) {
179
+ result.push(await fn(array[i], i, array));
180
+ }
181
+ return result;
182
+ });
183
+ this.global.define('filter', async (array, fn) => {
184
+ if (!Array.isArray(array)) {
185
+ throw new RuntimeError('filter() expects an array', null, this.source);
186
+ }
187
+ if (typeof fn !== 'function') {
188
+ throw new RuntimeError('filter() expects a function', null, this.source);
189
+ }
190
+
191
+ const result = [];
192
+ for (let i = 0; i < array.length; i++) {
193
+ if (await fn(array[i], i, array)) {
194
+ result.push(array[i]);
195
+ }
196
+ }
197
+ return result;
198
+ });
199
+ this.global.define('reduce', async (array, fn, initial) => {
200
+ if (!Array.isArray(array)) {
201
+ throw new RuntimeError('reduce() expects an array', null, this.source);
202
+ }
203
+ if (typeof fn !== 'function') {
204
+ throw new RuntimeError('reduce() expects a function', null, this.source);
205
+ }
206
+
207
+ let acc;
208
+ let startIndex = 0;
209
+
210
+ if (initial !== undefined) {
211
+ acc = initial;
212
+ } else {
213
+ if (array.length === 0) {
214
+ throw new RuntimeError('reduce() of empty array with no initial value', null, this.source);
215
+ }
216
+ acc = array[0];
217
+ startIndex = 1;
218
+ }
219
+
220
+ for (let i = startIndex; i < array.length; i++) {
221
+ acc = await fn(acc, array[i], i, array);
222
+ }
223
+
224
+ return acc;
225
+ });
226
+
169
227
  this.global.define('keys', arg => arg && typeof arg === 'object' ? Object.keys(arg) : []);
170
228
  this.global.define('values', arg => arg && typeof arg === 'object' ? Object.values(arg) : []);
171
229
  this.global.define('range', (...args) => {
package/src/starlight.js CHANGED
@@ -12,7 +12,7 @@ const Lexer = require('./lexer');
12
12
  const Parser = require('./parser');
13
13
  const Evaluator = require('./evaluator');
14
14
 
15
- const VERSION = '1.1.5';
15
+ const VERSION = '1.1.6';
16
16
 
17
17
  const COLOR = {
18
18
  reset: '\x1b[0m',