@almadar/evaluator 2.38.0 → 2.40.0

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.
@@ -1,4 +1,4 @@
1
- import { UserContext, TraitConfig, AgentContext, LlmContext, WorkspaceContext, SessionContext, MemoryContext, TraceContext, IntegrationContext, SExpr } from '@almadar/core';
1
+ import { UserContext, TraitConfig, NavItem, AgentContext, LlmContext, WorkspaceContext, SessionContext, MemoryContext, TraceContext, IntegrationContext, SExpr } from '@almadar/core';
2
2
 
3
3
  /**
4
4
  * Evaluation Context
@@ -35,6 +35,23 @@ interface EvaluationContext {
35
35
  * trait ref; the atom's render-ui reads `@config.icon`, `@config.title`, etc.
36
36
  */
37
37
  config?: TraitConfig;
38
+ /**
39
+ * The host orbital's pages as a `NavItem[]` for the `@pages` render sigil
40
+ * (`href = page.path`, `label = page.name`). Seeded into the render binding
41
+ * context only — never present on a guard context (`createMinimalContext`),
42
+ * so the sigil is render-resolved exactly like the compiler's
43
+ * `OirBindingRoot::Pages`. Mirrors `@currentTheme` / the compiler's
44
+ * post-pass substitution in `resolve_to_oir`.
45
+ */
46
+ pages?: NavItem[];
47
+ /**
48
+ * The `data-theme` selector-key string for the `@currentTheme` render sigil,
49
+ * derived from the host orbital's `Orbital.theme` (a `ThemeRef` name).
50
+ * Render-resolved only (never on a guard context). The knob that consumes
51
+ * it stays `string` — the renderer applies the theme via the `data-theme`
52
+ * attribute + CSS `[data-theme="..."]` blocks.
53
+ */
54
+ currentTheme?: string;
38
55
  /**
39
56
  * When true, log warnings when bindings resolve to undefined. (RCG-01)
40
57
  * Helps detect typos and missing entity fields early.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { SExpr, ListenPayloadEvaluator } from '@almadar/core';
2
2
  export { CORE_BINDINGS, CoreBinding, Expression, ExpressionSchema, ParsedBinding, SExpr, SExprAtom, SExprSchema, UserContext, collectBindings, getArgs, getOperator, isBinding, isSExpr, isSExprAtom, isSExprCall, isValidBinding, parseBinding, sexpr, walkSExpr } from '@almadar/core';
3
- import { E as EvaluationContext } from './index-dAA7DJ-s.js';
4
- export { c as createChildContext, a as createEffectContext, b as createMinimalContext, e as evalAbs, d as evalAdd, f as evalAnd, g as evalAtomic, h as evalCallService, i as evalCeil, j as evalClamp, k as evalConcat, l as evalCount, m as evalDecrement, n as evalDeref, o as evalDespawn, p as evalDivide, q as evalDo, r as evalEmit, s as evalEmpty, t as evalEqual, u as evalFilter, v as evalFind, w as evalFirst, x as evalFloor, y as evalFn, z as evalGreaterThan, A as evalGreaterThanOrEqual, B as evalIf, C as evalIncludes, D as evalIncrement, F as evalLast, G as evalLessThan, H as evalLessThanOrEqual, I as evalLet, J as evalList, K as evalMap, L as evalMatches, M as evalMax, N as evalMin, O as evalModulo, P as evalMultiply, Q as evalNavigate, R as evalNot, S as evalNotEqual, T as evalNotify, U as evalNth, V as evalOr, W as evalPersist, X as evalRef, Y as evalRenderUI, Z as evalRound, _ as evalSet, $ as evalSetDynamic, a0 as evalSpawn, a1 as evalSubtract, a2 as evalSum, a3 as evalSwap, a4 as evalWatch, a5 as evalWhen, a6 as resolveBinding } from './index-dAA7DJ-s.js';
3
+ import { E as EvaluationContext } from './index-BIg56YY8.js';
4
+ export { c as createChildContext, a as createEffectContext, b as createMinimalContext, e as evalAbs, d as evalAdd, f as evalAnd, g as evalAtomic, h as evalCallService, i as evalCeil, j as evalClamp, k as evalConcat, l as evalCount, m as evalDecrement, n as evalDeref, o as evalDespawn, p as evalDivide, q as evalDo, r as evalEmit, s as evalEmpty, t as evalEqual, u as evalFilter, v as evalFind, w as evalFirst, x as evalFloor, y as evalFn, z as evalGreaterThan, A as evalGreaterThanOrEqual, B as evalIf, C as evalIncludes, D as evalIncrement, F as evalLast, G as evalLessThan, H as evalLessThanOrEqual, I as evalLet, J as evalList, K as evalMap, L as evalMatches, M as evalMax, N as evalMin, O as evalModulo, P as evalMultiply, Q as evalNavigate, R as evalNot, S as evalNotEqual, T as evalNotify, U as evalNth, V as evalOr, W as evalPersist, X as evalRef, Y as evalRenderUI, Z as evalRound, _ as evalSet, $ as evalSetDynamic, a0 as evalSpawn, a1 as evalSubtract, a2 as evalSum, a3 as evalSwap, a4 as evalWatch, a5 as evalWhen, a6 as resolveBinding } from './index-BIg56YY8.js';
5
5
 
6
6
  /**
7
7
  * S-Expression Evaluator
package/dist/index.js CHANGED
@@ -69,6 +69,10 @@ function resolveBinding(binding, ctx) {
69
69
  case "config":
70
70
  value = ctx.config;
71
71
  break;
72
+ case "pages":
73
+ return ctx.pages;
74
+ case "currentTheme":
75
+ return ctx.currentTheme;
72
76
  default:
73
77
  value = ctx.singletons.get(root);
74
78
  break;
@@ -1780,6 +1784,104 @@ var MS_PER_MINUTE = 60 * MS_PER_SECOND;
1780
1784
  var MS_PER_HOUR = 60 * MS_PER_MINUTE;
1781
1785
  var MS_PER_DAY = 24 * MS_PER_HOUR;
1782
1786
  var MS_PER_WEEK = 7 * MS_PER_DAY;
1787
+ var TIME_UNIT_ALIASES = {
1788
+ ms: "ms",
1789
+ millisecond: "ms",
1790
+ milliseconds: "ms",
1791
+ s: "second",
1792
+ second: "second",
1793
+ seconds: "second",
1794
+ m: "minute",
1795
+ minute: "minute",
1796
+ minutes: "minute",
1797
+ h: "hour",
1798
+ hour: "hour",
1799
+ hours: "hour",
1800
+ d: "day",
1801
+ day: "day",
1802
+ days: "day",
1803
+ w: "week",
1804
+ week: "week",
1805
+ weeks: "week",
1806
+ month: "month",
1807
+ months: "month",
1808
+ year: "year",
1809
+ years: "year"
1810
+ };
1811
+ var TIME_UNIT_VOCABULARY = "ms|millisecond(s), s|second(s), m|minute(s), h|hour(s), d|day(s), w|week(s), month(s), year(s)";
1812
+ function parseTimeUnit(unit) {
1813
+ const resolved = TIME_UNIT_ALIASES[String(unit)];
1814
+ if (resolved === void 0) {
1815
+ throw new TypeError(
1816
+ `Type mismatch: expected time unit (${TIME_UNIT_VOCABULARY}), got ${String(unit)}`
1817
+ );
1818
+ }
1819
+ return resolved;
1820
+ }
1821
+ var FIXED_UNIT_MS = {
1822
+ ms: 1,
1823
+ second: MS_PER_SECOND,
1824
+ minute: MS_PER_MINUTE,
1825
+ hour: MS_PER_HOUR,
1826
+ day: MS_PER_DAY,
1827
+ week: MS_PER_WEEK
1828
+ };
1829
+ function daysInMonth(year, month) {
1830
+ return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();
1831
+ }
1832
+ function addCalendarMonths(ts, months) {
1833
+ const date = new Date(ts);
1834
+ const y = date.getUTCFullYear();
1835
+ const m = date.getUTCMonth();
1836
+ const total = y * 12 + m + months;
1837
+ const ny = Math.floor(total / 12);
1838
+ const nm = (total % 12 + 12) % 12;
1839
+ const nd = Math.min(date.getUTCDate(), daysInMonth(ny, nm));
1840
+ const shifted = new Date(ts);
1841
+ shifted.setUTCFullYear(ny, nm, nd);
1842
+ return shifted.getTime();
1843
+ }
1844
+ function shiftTime(ts, amount, unit) {
1845
+ const fixed = FIXED_UNIT_MS[unit];
1846
+ if (fixed !== void 0) return ts + amount * fixed;
1847
+ return addCalendarMonths(ts, unit === "year" ? Math.trunc(amount) * 12 : Math.trunc(amount));
1848
+ }
1849
+ function startOf(ts, unit) {
1850
+ switch (unit) {
1851
+ case "ms":
1852
+ return Math.floor(ts);
1853
+ case "second":
1854
+ return Math.floor(ts / MS_PER_SECOND) * MS_PER_SECOND;
1855
+ case "minute":
1856
+ return Math.floor(ts / MS_PER_MINUTE) * MS_PER_MINUTE;
1857
+ case "hour":
1858
+ return Math.floor(ts / MS_PER_HOUR) * MS_PER_HOUR;
1859
+ case "day":
1860
+ return Math.floor(ts / MS_PER_DAY) * MS_PER_DAY;
1861
+ case "week": {
1862
+ const days = Math.floor(ts / MS_PER_DAY);
1863
+ const dow = ((days + 3) % 7 + 7) % 7;
1864
+ return (days - dow) * MS_PER_DAY;
1865
+ }
1866
+ case "month": {
1867
+ const d = new Date(ts);
1868
+ return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), 1);
1869
+ }
1870
+ case "year":
1871
+ return Date.UTC(new Date(ts).getUTCFullYear(), 0, 1);
1872
+ }
1873
+ }
1874
+ function wholeMonthsBetween(from, to) {
1875
+ const lo = new Date(Math.min(from, to));
1876
+ const hi = new Date(Math.max(from, to));
1877
+ let months = (hi.getUTCFullYear() - lo.getUTCFullYear()) * 12 + (hi.getUTCMonth() - lo.getUTCMonth());
1878
+ const loRest = [lo.getUTCDate(), lo.getTime() - startOf(lo.getTime(), "day")];
1879
+ const hiRest = [hi.getUTCDate(), hi.getTime() - startOf(hi.getTime(), "day")];
1880
+ if (hiRest[0] < loRest[0] || hiRest[0] === loRest[0] && hiRest[1] < loRest[1]) {
1881
+ months -= 1;
1882
+ }
1883
+ return to < from ? -months : months;
1884
+ }
1783
1885
  function evalTimeNow() {
1784
1886
  return Date.now();
1785
1887
  }
@@ -1862,136 +1964,39 @@ function evalTimeSecond(args, evaluate2, ctx) {
1862
1964
  const timestamp = evaluate2(args[0], ctx);
1863
1965
  return new Date(timestamp).getSeconds();
1864
1966
  }
1865
- function addTime(date, amount, unit) {
1866
- const result = new Date(date);
1867
- switch (unit) {
1868
- case "year":
1869
- result.setFullYear(result.getFullYear() + amount);
1870
- break;
1871
- case "month":
1872
- result.setMonth(result.getMonth() + amount);
1873
- break;
1874
- case "week":
1875
- result.setDate(result.getDate() + amount * 7);
1876
- break;
1877
- case "day":
1878
- result.setDate(result.getDate() + amount);
1879
- break;
1880
- case "hour":
1881
- result.setHours(result.getHours() + amount);
1882
- break;
1883
- case "minute":
1884
- result.setMinutes(result.getMinutes() + amount);
1885
- break;
1886
- case "second":
1887
- result.setSeconds(result.getSeconds() + amount);
1888
- break;
1889
- case "ms":
1890
- result.setMilliseconds(result.getMilliseconds() + amount);
1891
- break;
1892
- }
1893
- return result;
1894
- }
1895
1967
  function evalTimeAdd(args, evaluate2, ctx) {
1896
1968
  const timestamp = evaluate2(args[0], ctx);
1897
1969
  const amount = evaluate2(args[1], ctx);
1898
- const unit = evaluate2(args[2], ctx);
1899
- const date = new Date(timestamp);
1900
- return addTime(date, amount, unit).getTime();
1970
+ const unit = parseTimeUnit(evaluate2(args[2], ctx));
1971
+ return shiftTime(timestamp, amount, unit);
1901
1972
  }
1902
1973
  function evalTimeSubtract(args, evaluate2, ctx) {
1903
1974
  const timestamp = evaluate2(args[0], ctx);
1904
1975
  const amount = evaluate2(args[1], ctx);
1905
- const unit = evaluate2(args[2], ctx);
1906
- const date = new Date(timestamp);
1907
- return addTime(date, -amount, unit).getTime();
1976
+ const unit = parseTimeUnit(evaluate2(args[2], ctx));
1977
+ return shiftTime(timestamp, -amount, unit);
1908
1978
  }
1909
1979
  function evalTimeDiff(args, evaluate2, ctx) {
1910
1980
  const a = evaluate2(args[0], ctx);
1911
1981
  const b = evaluate2(args[1], ctx);
1912
- const unit = args.length > 2 ? evaluate2(args[2], ctx) : "ms";
1913
1982
  const diffMs = a - b;
1914
- switch (unit) {
1915
- case "year":
1916
- return Math.floor(diffMs / (MS_PER_DAY * 365.25));
1917
- case "month":
1918
- return Math.floor(diffMs / (MS_PER_DAY * 30.44));
1919
- case "week":
1920
- return Math.floor(diffMs / MS_PER_WEEK);
1921
- case "day":
1922
- return Math.floor(diffMs / MS_PER_DAY);
1923
- case "hour":
1924
- return Math.floor(diffMs / MS_PER_HOUR);
1925
- case "minute":
1926
- return Math.floor(diffMs / MS_PER_MINUTE);
1927
- case "second":
1928
- return Math.floor(diffMs / MS_PER_SECOND);
1929
- case "ms":
1930
- default:
1931
- return diffMs;
1932
- }
1983
+ if (args.length <= 2) return diffMs;
1984
+ const unit = parseTimeUnit(evaluate2(args[2], ctx));
1985
+ const fixed = FIXED_UNIT_MS[unit];
1986
+ if (fixed !== void 0) return Math.trunc(diffMs / fixed);
1987
+ const months = wholeMonthsBetween(b, a);
1988
+ return unit === "year" ? Math.trunc(months / 12) : months;
1933
1989
  }
1934
1990
  function evalTimeStartOf(args, evaluate2, ctx) {
1935
1991
  const timestamp = evaluate2(args[0], ctx);
1936
- const unit = evaluate2(args[1], ctx);
1937
- const date = new Date(timestamp);
1938
- switch (unit) {
1939
- case "year":
1940
- date.setMonth(0, 1);
1941
- date.setHours(0, 0, 0, 0);
1942
- break;
1943
- case "month":
1944
- date.setDate(1);
1945
- date.setHours(0, 0, 0, 0);
1946
- break;
1947
- case "week": {
1948
- const day = date.getDay();
1949
- date.setDate(date.getDate() - day);
1950
- date.setHours(0, 0, 0, 0);
1951
- break;
1952
- }
1953
- case "day":
1954
- date.setHours(0, 0, 0, 0);
1955
- break;
1956
- case "hour":
1957
- date.setMinutes(0, 0, 0);
1958
- break;
1959
- case "minute":
1960
- date.setSeconds(0, 0);
1961
- break;
1962
- }
1963
- return date.getTime();
1992
+ const unit = parseTimeUnit(evaluate2(args[1], ctx));
1993
+ return startOf(timestamp, unit);
1964
1994
  }
1965
1995
  function evalTimeEndOf(args, evaluate2, ctx) {
1966
1996
  const timestamp = evaluate2(args[0], ctx);
1967
- const unit = evaluate2(args[1], ctx);
1968
- const date = new Date(timestamp);
1969
- switch (unit) {
1970
- case "year":
1971
- date.setMonth(11, 31);
1972
- date.setHours(23, 59, 59, 999);
1973
- break;
1974
- case "month":
1975
- date.setMonth(date.getMonth() + 1, 0);
1976
- date.setHours(23, 59, 59, 999);
1977
- break;
1978
- case "week": {
1979
- const day = date.getDay();
1980
- date.setDate(date.getDate() + (6 - day));
1981
- date.setHours(23, 59, 59, 999);
1982
- break;
1983
- }
1984
- case "day":
1985
- date.setHours(23, 59, 59, 999);
1986
- break;
1987
- case "hour":
1988
- date.setMinutes(59, 59, 999);
1989
- break;
1990
- case "minute":
1991
- date.setSeconds(59, 999);
1992
- break;
1993
- }
1994
- return date.getTime();
1997
+ const unit = parseTimeUnit(evaluate2(args[1], ctx));
1998
+ if (unit === "ms") return Math.floor(timestamp);
1999
+ return shiftTime(startOf(timestamp, unit), 1, unit) - 1;
1995
2000
  }
1996
2001
  function evalTimeIsBefore(args, evaluate2, ctx) {
1997
2002
  const a = evaluate2(args[0], ctx);
@@ -2012,28 +2017,11 @@ function evalTimeIsBetween(args, evaluate2, ctx) {
2012
2017
  function evalTimeIsSame(args, evaluate2, ctx) {
2013
2018
  const a = evaluate2(args[0], ctx);
2014
2019
  const b = evaluate2(args[1], ctx);
2015
- const unit = args.length > 2 ? evaluate2(args[2], ctx) : void 0;
2016
- if (!unit) {
2020
+ if (args.length <= 2) {
2017
2021
  return a === b;
2018
2022
  }
2019
- const dateA = new Date(a);
2020
- const dateB = new Date(b);
2021
- switch (unit) {
2022
- case "year":
2023
- return dateA.getFullYear() === dateB.getFullYear();
2024
- case "month":
2025
- return dateA.getFullYear() === dateB.getFullYear() && dateA.getMonth() === dateB.getMonth();
2026
- case "day":
2027
- return dateA.getFullYear() === dateB.getFullYear() && dateA.getMonth() === dateB.getMonth() && dateA.getDate() === dateB.getDate();
2028
- case "hour":
2029
- return dateA.getFullYear() === dateB.getFullYear() && dateA.getMonth() === dateB.getMonth() && dateA.getDate() === dateB.getDate() && dateA.getHours() === dateB.getHours();
2030
- case "minute":
2031
- return Math.floor(a / MS_PER_MINUTE) === Math.floor(b / MS_PER_MINUTE);
2032
- case "second":
2033
- return Math.floor(a / MS_PER_SECOND) === Math.floor(b / MS_PER_SECOND);
2034
- default:
2035
- return a === b;
2036
- }
2023
+ const unit = parseTimeUnit(evaluate2(args[2], ctx));
2024
+ return startOf(a, unit) === startOf(b, unit);
2037
2025
  }
2038
2026
  function evalTimeIsPast(args, evaluate2, ctx) {
2039
2027
  const timestamp = evaluate2(args[0], ctx);