littlewing 0.7.1 → 0.8.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
@@ -209,23 +209,21 @@ interface ExecutionContext {
209
209
 
210
210
  The `defaultContext` includes these built-in functions:
211
211
 
212
- **Math:** `ABS`, `CEIL`, `FLOOR`, `ROUND`, `SQRT`, `MIN`, `MAX`, `SIN`, `COS`, `TAN`, `LOG`, `LOG10`, `EXP`
212
+ **Math:** `ABS`, `CEIL`, `FLOOR`, `ROUND`, `SQRT`, `MIN`, `MAX`, `CLAMP`, `SIN`, `COS`, `TAN`, `LOG`, `LOG10`, `EXP`
213
213
 
214
214
  **Timestamps:** `NOW`, `DATE`
215
215
 
216
- **Time converters (to milliseconds):** `FROM_SECONDS`, `FROM_MINUTES`, `FROM_HOURS`, `FROM_DAYS`, `FROM_WEEKS`, `FROM_MONTHS`, `FROM_YEARS`
216
+ **Time converters (to milliseconds):** `FROM_DAYS`, `FROM_WEEKS`, `FROM_MONTHS`, `FROM_YEARS`
217
217
 
218
218
  **Date component extractors:** `GET_YEAR`, `GET_MONTH`, `GET_DAY`, `GET_HOUR`, `GET_MINUTE`, `GET_SECOND`, `GET_WEEKDAY`, `GET_MILLISECOND`, `GET_DAY_OF_YEAR`, `GET_QUARTER`
219
219
 
220
- **Time differences (always positive):** `DIFFERENCE_IN_SECONDS`, `DIFFERENCE_IN_MINUTES`, `DIFFERENCE_IN_HOURS`, `DIFFERENCE_IN_DAYS`, `DIFFERENCE_IN_WEEKS`
220
+ **Time differences (always positive):** `DIFFERENCE_IN_SECONDS`, `DIFFERENCE_IN_MINUTES`, `DIFFERENCE_IN_HOURS`, `DIFFERENCE_IN_DAYS`, `DIFFERENCE_IN_WEEKS`, `DIFFERENCE_IN_MONTHS`, `DIFFERENCE_IN_YEARS`
221
221
 
222
222
  **Start/End of period:** `START_OF_DAY`, `END_OF_DAY`, `START_OF_WEEK`, `START_OF_MONTH`, `END_OF_MONTH`, `START_OF_YEAR`, `END_OF_YEAR`, `START_OF_QUARTER`
223
223
 
224
224
  **Date arithmetic:** `ADD_DAYS`, `ADD_MONTHS`, `ADD_YEARS`
225
225
 
226
- **Date comparisons:** `IS_BEFORE`, `IS_AFTER`, `IS_SAME_DAY`, `IS_WEEKEND`, `IS_LEAP_YEAR`
227
-
228
- **Unix time:** `TO_UNIX_SECONDS`, `FROM_UNIX_SECONDS`
226
+ **Date comparisons:** `IS_SAME_DAY`, `IS_WEEKEND`, `IS_LEAP_YEAR` (use `<`, `>`, `<=`, `>=` operators for before/after comparisons)
229
227
 
230
228
  ## Use Cases
231
229
 
package/dist/index.d.ts CHANGED
@@ -317,35 +317,29 @@ declare class CodeGenerator {
317
317
  */
318
318
  declare function generate(node: ASTNode): string;
319
319
  declare namespace exports_date_utils {
320
- export { TO_UNIX_SECONDS, START_OF_YEAR, START_OF_WEEK, START_OF_QUARTER, START_OF_MONTH, START_OF_DAY, NOW, IS_WEEKEND, IS_SAME_DAY, IS_LEAP_YEAR, IS_BEFORE, IS_AFTER, GET_YEAR, GET_WEEKDAY, GET_SECOND, GET_QUARTER, GET_MONTH, GET_MINUTE, GET_MILLISECOND, GET_HOUR, GET_DAY_OF_YEAR, GET_DAY, FROM_YEARS, FROM_WEEKS, FROM_UNIX_SECONDS, FROM_SECONDS, FROM_MONTHS, FROM_MINUTES, FROM_HOURS, FROM_DAYS, END_OF_YEAR, END_OF_MONTH, END_OF_DAY, DIFFERENCE_IN_WEEKS, DIFFERENCE_IN_SECONDS, DIFFERENCE_IN_MINUTES, DIFFERENCE_IN_HOURS, DIFFERENCE_IN_DAYS, DATE, ADD_YEARS, ADD_MONTHS, ADD_DAYS };
320
+ export { START_OF_YEAR, START_OF_WEEK, START_OF_QUARTER, START_OF_MONTH, START_OF_DAY, NOW, IS_WEEKEND, IS_SAME_DAY, IS_LEAP_YEAR, GET_YEAR, GET_WEEKDAY, GET_SECOND, GET_QUARTER, GET_MONTH, GET_MINUTE, GET_MILLISECOND, GET_HOUR, GET_DAY_OF_YEAR, GET_DAY, FROM_YEARS, FROM_WEEKS, FROM_MONTHS, FROM_DAYS, END_OF_YEAR, END_OF_MONTH, END_OF_DAY, DIFFERENCE_IN_YEARS, DIFFERENCE_IN_WEEKS, DIFFERENCE_IN_SECONDS, DIFFERENCE_IN_MONTHS, DIFFERENCE_IN_MINUTES, DIFFERENCE_IN_HOURS, DIFFERENCE_IN_DAYS, DATE, ADD_YEARS, ADD_MONTHS, ADD_DAYS };
321
321
  }
322
322
  /**
323
323
  * Date utility functions for working with timestamps
324
324
  * All functions work with milliseconds since Unix epoch (numbers only)
325
+ *
326
+ * IMPORTANT: All functions use local timezone to match the user's context.
327
+ * In a browser, this reflects the user's timezone. On a server, this reflects
328
+ * the server's configured timezone. This ensures date calculations align with
329
+ * the user's calendar expectations.
325
330
  */
326
331
  /**
327
332
  * Get current timestamp (milliseconds since Unix epoch)
328
333
  */
329
334
  declare const NOW: () => number;
330
335
  /**
331
- * Create timestamp from date components
336
+ * Create timestamp from date components (local timezone)
332
337
  * Year is required, all other parameters default to minimum values
333
338
  * Month is 1-based (1 = January, 12 = December)
339
+ * All parameters are interpreted in local timezone
334
340
  */
335
341
  declare const DATE: (year: number, month?: number, day?: number, hour?: number, minute?: number, second?: number) => number;
336
342
  /**
337
- * Convert seconds to milliseconds
338
- */
339
- declare const FROM_SECONDS: (s: number) => number;
340
- /**
341
- * Convert minutes to milliseconds
342
- */
343
- declare const FROM_MINUTES: (m: number) => number;
344
- /**
345
- * Convert hours to milliseconds
346
- */
347
- declare const FROM_HOURS: (h: number) => number;
348
- /**
349
343
  * Convert days to milliseconds
350
344
  */
351
345
  declare const FROM_DAYS: (d: number) => number;
@@ -355,150 +349,162 @@ declare const FROM_DAYS: (d: number) => number;
355
349
  declare const FROM_WEEKS: (w: number) => number;
356
350
  /**
357
351
  * Convert months to milliseconds (approximate: 30 days per month)
352
+ * WARNING: This is an approximation. Not all months have 30 days.
353
+ * For accurate month arithmetic, use ADD_MONTHS() instead.
358
354
  */
359
355
  declare const FROM_MONTHS: (months: number) => number;
360
356
  /**
361
357
  * Convert years to milliseconds (approximate: 365 days per year)
358
+ * WARNING: This is an approximation. Leap years have 366 days.
359
+ * For accurate year arithmetic, use ADD_YEARS() instead.
362
360
  */
363
361
  declare const FROM_YEARS: (years: number) => number;
364
362
  /**
365
- * Get the year from a timestamp
363
+ * Get the year from a timestamp (local timezone)
366
364
  */
367
365
  declare const GET_YEAR: (timestamp: number) => number;
368
366
  /**
369
- * Get the month from a timestamp (1-based: 1 = January, 12 = December)
367
+ * Get the month from a timestamp (1-based: 1 = January, 12 = December, local timezone)
370
368
  */
371
369
  declare const GET_MONTH: (timestamp: number) => number;
372
370
  /**
373
- * Get the day of month from a timestamp (1-31)
371
+ * Get the day of month from a timestamp (1-31, local timezone)
374
372
  */
375
373
  declare const GET_DAY: (timestamp: number) => number;
376
374
  /**
377
- * Get the hour from a timestamp (0-23)
375
+ * Get the hour from a timestamp (0-23, local timezone)
378
376
  */
379
377
  declare const GET_HOUR: (timestamp: number) => number;
380
378
  /**
381
- * Get the minute from a timestamp (0-59)
379
+ * Get the minute from a timestamp (0-59, local timezone)
382
380
  */
383
381
  declare const GET_MINUTE: (timestamp: number) => number;
384
382
  /**
385
- * Get the second from a timestamp (0-59)
383
+ * Get the second from a timestamp (0-59, local timezone)
386
384
  */
387
385
  declare const GET_SECOND: (timestamp: number) => number;
388
386
  /**
389
- * Get the millisecond component from a timestamp (0-999)
387
+ * Get the millisecond component from a timestamp (0-999, local timezone)
390
388
  */
391
389
  declare const GET_MILLISECOND: (timestamp: number) => number;
392
390
  /**
393
- * Get the day of week from a timestamp (0 = Sunday, 6 = Saturday)
391
+ * Get the day of week from a timestamp (0 = Sunday, 6 = Saturday, local timezone)
394
392
  */
395
393
  declare const GET_WEEKDAY: (timestamp: number) => number;
396
394
  /**
397
- * Get the day of year (1-366) from a timestamp
395
+ * Get the day of year (1-366) from a timestamp (local timezone)
396
+ * January 1st = 1, December 31st = 365 or 366 (leap year)
398
397
  */
399
398
  declare const GET_DAY_OF_YEAR: (timestamp: number) => number;
400
399
  /**
401
- * Get the quarter (1-4) from a timestamp
400
+ * Get the quarter (1-4) from a timestamp (local timezone)
402
401
  */
403
402
  declare const GET_QUARTER: (timestamp: number) => number;
404
403
  /**
405
- * Get the absolute difference between two timestamps in seconds
404
+ * Get the absolute difference between two timestamps in seconds (whole seconds)
406
405
  */
407
406
  declare const DIFFERENCE_IN_SECONDS: (ts1: number, ts2: number) => number;
408
407
  /**
409
- * Get the absolute difference between two timestamps in minutes
408
+ * Get the absolute difference between two timestamps in minutes (whole minutes)
410
409
  */
411
410
  declare const DIFFERENCE_IN_MINUTES: (ts1: number, ts2: number) => number;
412
411
  /**
413
- * Get the absolute difference between two timestamps in hours
412
+ * Get the absolute difference between two timestamps in hours (whole hours)
414
413
  */
415
414
  declare const DIFFERENCE_IN_HOURS: (ts1: number, ts2: number) => number;
416
415
  /**
417
- * Get the absolute difference between two timestamps in days
416
+ * Get the difference in calendar days between two timestamps
417
+ * Counts the number of calendar day boundaries crossed, not 24-hour periods
418
+ * Example: Nov 7 at 11:59 PM to Nov 8 at 12:01 AM = 1 day (different calendar days)
418
419
  */
419
420
  declare const DIFFERENCE_IN_DAYS: (ts1: number, ts2: number) => number;
420
421
  /**
421
- * Get the absolute difference between two timestamps in weeks
422
+ * Get the difference in calendar weeks between two timestamps
423
+ * Counts the number of week boundaries crossed (based on calendar days)
422
424
  */
423
425
  declare const DIFFERENCE_IN_WEEKS: (ts1: number, ts2: number) => number;
424
426
  /**
425
- * Get the start of day (00:00:00.000) for a given timestamp
427
+ * Get the number of full calendar months between two timestamps (local timezone)
428
+ * Counts complete months where the same day-of-month has been reached
429
+ *
430
+ * Examples:
431
+ * Jan 15 → Feb 14 = 0 months (Feb 15 not reached yet)
432
+ * Jan 15 → Feb 15 = 1 month
433
+ * Jan 31 → Feb 28 = 0 months (Feb 31 doesn't exist)
434
+ * Jan 31 → Mar 31 = 2 months
435
+ */
436
+ declare const DIFFERENCE_IN_MONTHS: (ts1: number, ts2: number) => number;
437
+ /**
438
+ * Get the number of full calendar years between two timestamps (local timezone)
439
+ * Counts complete years where the same month and day have been reached
440
+ *
441
+ * Examples:
442
+ * Jan 15, 2020 → Jan 14, 2021 = 0 years (Jan 15 not reached)
443
+ * Jan 15, 2020 → Jan 15, 2021 = 1 year
444
+ * Feb 29, 2020 → Feb 28, 2021 = 0 years (Feb 29 doesn't exist)
445
+ * Feb 29, 2020 → Mar 1, 2021 = 1 year
446
+ */
447
+ declare const DIFFERENCE_IN_YEARS: (ts1: number, ts2: number) => number;
448
+ /**
449
+ * Get the start of day (00:00:00.000 local time) for a given timestamp
426
450
  */
427
451
  declare const START_OF_DAY: (timestamp: number) => number;
428
452
  /**
429
- * Get the end of day (23:59:59.999) for a given timestamp
453
+ * Get the end of day (23:59:59.999 local time) for a given timestamp
430
454
  */
431
455
  declare const END_OF_DAY: (timestamp: number) => number;
432
456
  /**
433
- * Get the start of week (Sunday at 00:00:00.000) for a given timestamp
457
+ * Get the start of week (Sunday at 00:00:00.000 local time) for a given timestamp
434
458
  */
435
459
  declare const START_OF_WEEK: (timestamp: number) => number;
436
460
  /**
437
- * Get the start of month (1st day at 00:00:00.000) for a given timestamp
461
+ * Get the start of month (1st day at 00:00:00.000 local time) for a given timestamp
438
462
  */
439
463
  declare const START_OF_MONTH: (timestamp: number) => number;
440
464
  /**
441
- * Get the end of month (last day at 23:59:59.999) for a given timestamp
465
+ * Get the end of month (last day at 23:59:59.999 local time) for a given timestamp
442
466
  */
443
467
  declare const END_OF_MONTH: (timestamp: number) => number;
444
468
  /**
445
- * Get the start of year (Jan 1st at 00:00:00.000) for a given timestamp
469
+ * Get the start of year (Jan 1st at 00:00:00.000 local time) for a given timestamp
446
470
  */
447
471
  declare const START_OF_YEAR: (timestamp: number) => number;
448
472
  /**
449
- * Get the end of year (Dec 31st at 23:59:59.999) for a given timestamp
473
+ * Get the end of year (Dec 31st at 23:59:59.999 local time) for a given timestamp
450
474
  */
451
475
  declare const END_OF_YEAR: (timestamp: number) => number;
452
476
  /**
453
- * Add days to a timestamp
477
+ * Add days to a timestamp (local timezone)
454
478
  */
455
479
  declare const ADD_DAYS: (timestamp: number, days: number) => number;
456
480
  /**
457
- * Add months to a timestamp (handles variable month lengths correctly)
481
+ * Add months to a timestamp (handles variable month lengths correctly, local timezone)
458
482
  */
459
483
  declare const ADD_MONTHS: (timestamp: number, months: number) => number;
460
484
  /**
461
- * Add years to a timestamp
485
+ * Add years to a timestamp (local timezone)
462
486
  */
463
487
  declare const ADD_YEARS: (timestamp: number, years: number) => number;
464
488
  /**
465
- * Check if ts1 is before ts2
466
- * Returns 1 if true, 0 if false
467
- */
468
- declare const IS_BEFORE: (ts1: number, ts2: number) => number;
469
- /**
470
- * Check if ts1 is after ts2
471
- * Returns 1 if true, 0 if false
472
- */
473
- declare const IS_AFTER: (ts1: number, ts2: number) => number;
474
- /**
475
- * Check if two timestamps are on the same calendar day
489
+ * Check if two timestamps are on the same calendar day (local timezone)
476
490
  * Returns 1 if true, 0 if false
477
491
  */
478
492
  declare const IS_SAME_DAY: (ts1: number, ts2: number) => number;
479
493
  /**
480
- * Check if timestamp falls on a weekend (Saturday or Sunday)
494
+ * Check if timestamp falls on a weekend (Saturday or Sunday, local timezone)
481
495
  * Returns 1 if true, 0 if false
482
496
  */
483
497
  declare const IS_WEEKEND: (timestamp: number) => number;
484
498
  /**
485
- * Check if timestamp is in a leap year
499
+ * Check if timestamp is in a leap year (local timezone)
486
500
  * Returns 1 if true, 0 if false
487
501
  */
488
502
  declare const IS_LEAP_YEAR: (timestamp: number) => number;
489
503
  /**
490
- * Get the start of quarter for a given timestamp
504
+ * Get the start of quarter for a given timestamp (local timezone)
491
505
  */
492
506
  declare const START_OF_QUARTER: (timestamp: number) => number;
493
507
  /**
494
- * Convert millisecond timestamp to Unix seconds
495
- */
496
- declare const TO_UNIX_SECONDS: (timestamp: number) => number;
497
- /**
498
- * Convert Unix seconds to millisecond timestamp
499
- */
500
- declare const FROM_UNIX_SECONDS: (seconds: number) => number;
501
- /**
502
508
  * Default execution context with common Math functions and date/time utilities
503
509
  * Users can use this as-is or spread it into their own context
504
510
  *
package/dist/index.js CHANGED
@@ -410,7 +410,6 @@ function generate(node) {
410
410
  // src/date-utils.ts
411
411
  var exports_date_utils = {};
412
412
  __export(exports_date_utils, {
413
- TO_UNIX_SECONDS: () => TO_UNIX_SECONDS,
414
413
  START_OF_YEAR: () => START_OF_YEAR,
415
414
  START_OF_WEEK: () => START_OF_WEEK,
416
415
  START_OF_QUARTER: () => START_OF_QUARTER,
@@ -420,8 +419,6 @@ __export(exports_date_utils, {
420
419
  IS_WEEKEND: () => IS_WEEKEND,
421
420
  IS_SAME_DAY: () => IS_SAME_DAY,
422
421
  IS_LEAP_YEAR: () => IS_LEAP_YEAR,
423
- IS_BEFORE: () => IS_BEFORE,
424
- IS_AFTER: () => IS_AFTER,
425
422
  GET_YEAR: () => GET_YEAR,
426
423
  GET_WEEKDAY: () => GET_WEEKDAY,
427
424
  GET_SECOND: () => GET_SECOND,
@@ -434,17 +431,15 @@ __export(exports_date_utils, {
434
431
  GET_DAY: () => GET_DAY,
435
432
  FROM_YEARS: () => FROM_YEARS,
436
433
  FROM_WEEKS: () => FROM_WEEKS,
437
- FROM_UNIX_SECONDS: () => FROM_UNIX_SECONDS,
438
- FROM_SECONDS: () => FROM_SECONDS,
439
434
  FROM_MONTHS: () => FROM_MONTHS,
440
- FROM_MINUTES: () => FROM_MINUTES,
441
- FROM_HOURS: () => FROM_HOURS,
442
435
  FROM_DAYS: () => FROM_DAYS,
443
436
  END_OF_YEAR: () => END_OF_YEAR,
444
437
  END_OF_MONTH: () => END_OF_MONTH,
445
438
  END_OF_DAY: () => END_OF_DAY,
439
+ DIFFERENCE_IN_YEARS: () => DIFFERENCE_IN_YEARS,
446
440
  DIFFERENCE_IN_WEEKS: () => DIFFERENCE_IN_WEEKS,
447
441
  DIFFERENCE_IN_SECONDS: () => DIFFERENCE_IN_SECONDS,
442
+ DIFFERENCE_IN_MONTHS: () => DIFFERENCE_IN_MONTHS,
448
443
  DIFFERENCE_IN_MINUTES: () => DIFFERENCE_IN_MINUTES,
449
444
  DIFFERENCE_IN_HOURS: () => DIFFERENCE_IN_HOURS,
450
445
  DIFFERENCE_IN_DAYS: () => DIFFERENCE_IN_DAYS,
@@ -455,9 +450,6 @@ __export(exports_date_utils, {
455
450
  });
456
451
  var NOW = () => Date.now();
457
452
  var DATE = (year, month = 1, day = 1, hour = 0, minute = 0, second = 0) => new Date(year, month - 1, day, hour, minute, second).getTime();
458
- var FROM_SECONDS = (s) => s * 1000;
459
- var FROM_MINUTES = (m) => m * 60 * 1000;
460
- var FROM_HOURS = (h) => h * 60 * 60 * 1000;
461
453
  var FROM_DAYS = (d) => d * 24 * 60 * 60 * 1000;
462
454
  var FROM_WEEKS = (w) => w * 7 * 24 * 60 * 60 * 1000;
463
455
  var FROM_MONTHS = (months) => months * 30 * 24 * 60 * 60 * 1000;
@@ -472,82 +464,86 @@ var GET_MILLISECOND = (timestamp) => new Date(timestamp).getMilliseconds();
472
464
  var GET_WEEKDAY = (timestamp) => new Date(timestamp).getDay();
473
465
  var GET_DAY_OF_YEAR = (timestamp) => {
474
466
  const date = new Date(timestamp);
475
- const start = new Date(date.getFullYear(), 0, 0);
476
- const diff = date.getTime() - start.getTime();
477
- const oneDay = 1000 * 60 * 60 * 24;
478
- return Math.floor(diff / oneDay);
467
+ const year = date.getFullYear();
468
+ const startOfYear = new Date(year, 0, 1).getTime();
469
+ const diff = timestamp - startOfYear;
470
+ const oneDay = 86400000;
471
+ return Math.floor(diff / oneDay) + 1;
479
472
  };
480
473
  var GET_QUARTER = (timestamp) => {
481
474
  const month = new Date(timestamp).getMonth();
482
475
  return Math.floor(month / 3) + 1;
483
476
  };
484
- var DIFFERENCE_IN_SECONDS = (ts1, ts2) => Math.abs(ts1 - ts2) / 1000;
485
- var DIFFERENCE_IN_MINUTES = (ts1, ts2) => Math.abs(ts1 - ts2) / (60 * 1000);
486
- var DIFFERENCE_IN_HOURS = (ts1, ts2) => Math.abs(ts1 - ts2) / (60 * 60 * 1000);
487
- var DIFFERENCE_IN_DAYS = (ts1, ts2) => Math.abs(ts1 - ts2) / (24 * 60 * 60 * 1000);
488
- var DIFFERENCE_IN_WEEKS = (ts1, ts2) => Math.abs(ts1 - ts2) / (7 * 24 * 60 * 60 * 1000);
477
+ var DIFFERENCE_IN_SECONDS = (ts1, ts2) => Math.floor(Math.abs(ts1 - ts2) / 1000);
478
+ var DIFFERENCE_IN_MINUTES = (ts1, ts2) => Math.floor(Math.abs(ts1 - ts2) / (60 * 1000));
479
+ var DIFFERENCE_IN_HOURS = (ts1, ts2) => Math.floor(Math.abs(ts1 - ts2) / (60 * 60 * 1000));
480
+ var DIFFERENCE_IN_DAYS = (ts1, ts2) => {
481
+ const day1 = START_OF_DAY(ts1);
482
+ const day2 = START_OF_DAY(ts2);
483
+ return Math.floor(Math.abs(day1 - day2) / (24 * 60 * 60 * 1000));
484
+ };
485
+ var DIFFERENCE_IN_WEEKS = (ts1, ts2) => {
486
+ const days = DIFFERENCE_IN_DAYS(ts1, ts2);
487
+ return Math.floor(days / 7);
488
+ };
489
+ var DIFFERENCE_IN_MONTHS = (ts1, ts2) => {
490
+ const smaller = Math.min(ts1, ts2);
491
+ const larger = Math.max(ts1, ts2);
492
+ const date1 = new Date(smaller);
493
+ const date2 = new Date(larger);
494
+ const yearDiff = date2.getFullYear() - date1.getFullYear();
495
+ const monthDiff = date2.getMonth() - date1.getMonth();
496
+ let months = yearDiff * 12 + monthDiff;
497
+ if (date2.getDate() < date1.getDate()) {
498
+ months--;
499
+ }
500
+ return months;
501
+ };
502
+ var DIFFERENCE_IN_YEARS = (ts1, ts2) => {
503
+ return Math.floor(DIFFERENCE_IN_MONTHS(ts1, ts2) / 12);
504
+ };
489
505
  var START_OF_DAY = (timestamp) => {
490
506
  const date = new Date(timestamp);
491
- date.setHours(0, 0, 0, 0);
492
- return date.getTime();
507
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0, 0).getTime();
493
508
  };
494
509
  var END_OF_DAY = (timestamp) => {
495
510
  const date = new Date(timestamp);
496
- date.setHours(23, 59, 59, 999);
497
- return date.getTime();
511
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 23, 59, 59, 999).getTime();
498
512
  };
499
513
  var START_OF_WEEK = (timestamp) => {
500
514
  const date = new Date(timestamp);
501
- const day = date.getDay();
502
- const diff = date.getDate() - day;
503
- date.setDate(diff);
504
- date.setHours(0, 0, 0, 0);
505
- return date.getTime();
515
+ const dayOfWeek = date.getDay();
516
+ const currentDay = date.getDate();
517
+ const startDay = currentDay - dayOfWeek;
518
+ return new Date(date.getFullYear(), date.getMonth(), startDay, 0, 0, 0, 0).getTime();
506
519
  };
507
520
  var START_OF_MONTH = (timestamp) => {
508
521
  const date = new Date(timestamp);
509
- date.setDate(1);
510
- date.setHours(0, 0, 0, 0);
511
- return date.getTime();
522
+ return new Date(date.getFullYear(), date.getMonth(), 1, 0, 0, 0, 0).getTime();
512
523
  };
513
524
  var END_OF_MONTH = (timestamp) => {
514
525
  const date = new Date(timestamp);
515
- date.setMonth(date.getMonth() + 1, 0);
516
- date.setHours(23, 59, 59, 999);
517
- return date.getTime();
526
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0, 23, 59, 59, 999).getTime();
518
527
  };
519
528
  var START_OF_YEAR = (timestamp) => {
520
529
  const date = new Date(timestamp);
521
- date.setMonth(0, 1);
522
- date.setHours(0, 0, 0, 0);
523
- return date.getTime();
530
+ return new Date(date.getFullYear(), 0, 1, 0, 0, 0, 0).getTime();
524
531
  };
525
532
  var END_OF_YEAR = (timestamp) => {
526
533
  const date = new Date(timestamp);
527
- date.setMonth(11, 31);
528
- date.setHours(23, 59, 59, 999);
529
- return date.getTime();
534
+ return new Date(date.getFullYear(), 11, 31, 23, 59, 59, 999).getTime();
530
535
  };
531
536
  var ADD_DAYS = (timestamp, days) => {
532
537
  const date = new Date(timestamp);
533
- date.setDate(date.getDate() + days);
534
- return date.getTime();
538
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate() + days, date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()).getTime();
535
539
  };
536
540
  var ADD_MONTHS = (timestamp, months) => {
537
541
  const date = new Date(timestamp);
538
- date.setMonth(date.getMonth() + months);
539
- return date.getTime();
542
+ return new Date(date.getFullYear(), date.getMonth() + months, date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()).getTime();
540
543
  };
541
544
  var ADD_YEARS = (timestamp, years) => {
542
545
  const date = new Date(timestamp);
543
- date.setFullYear(date.getFullYear() + years);
544
- return date.getTime();
545
- };
546
- var IS_BEFORE = (ts1, ts2) => {
547
- return ts1 < ts2 ? 1 : 0;
548
- };
549
- var IS_AFTER = (ts1, ts2) => {
550
- return ts1 > ts2 ? 1 : 0;
546
+ return new Date(date.getFullYear() + years, date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()).getTime();
551
547
  };
552
548
  var IS_SAME_DAY = (ts1, ts2) => {
553
549
  const date1 = new Date(ts1);
@@ -564,13 +560,10 @@ var IS_LEAP_YEAR = (timestamp) => {
564
560
  };
565
561
  var START_OF_QUARTER = (timestamp) => {
566
562
  const date = new Date(timestamp);
567
- const quarter = Math.floor(date.getMonth() / 3);
568
- date.setMonth(quarter * 3, 1);
569
- date.setHours(0, 0, 0, 0);
570
- return date.getTime();
563
+ const month = date.getMonth();
564
+ const quarterStartMonth = Math.floor(month / 3) * 3;
565
+ return new Date(date.getFullYear(), quarterStartMonth, 1, 0, 0, 0, 0).getTime();
571
566
  };
572
- var TO_UNIX_SECONDS = (timestamp) => Math.floor(timestamp / 1000);
573
- var FROM_UNIX_SECONDS = (seconds) => seconds * 1000;
574
567
  // src/defaults.ts
575
568
  var defaultContext = {
576
569
  functions: {
@@ -587,6 +580,9 @@ var defaultContext = {
587
580
  LOG: Math.log,
588
581
  LOG10: Math.log10,
589
582
  EXP: Math.exp,
583
+ CLAMP: (value, min, max) => {
584
+ return value < min ? min : value > max ? max : value;
585
+ },
590
586
  ...exports_date_utils
591
587
  }
592
588
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "littlewing",
3
- "version": "0.7.1",
3
+ "version": "0.8.1",
4
4
  "description": "A minimal, high-performance arithmetic expression language with lexer, parser, and executor. Optimized for browsers with zero dependencies and type-safe execution.",
5
5
  "keywords": [
6
6
  "arithmetic",