@kalada/core 0.2.0 → 0.3.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.
Files changed (79) hide show
  1. package/dist/kalada-v1/canonical-input.cjs +133 -0
  2. package/dist/kalada-v1/canonical-input.cjs.map +1 -0
  3. package/dist/kalada-v1/canonical-input.d.cts +25 -0
  4. package/dist/kalada-v1/canonical-input.d.ts +25 -0
  5. package/dist/kalada-v1/canonical-input.js +122 -0
  6. package/dist/kalada-v1/canonical-input.js.map +1 -0
  7. package/dist/kalada-v1/canonicalize.cjs +78 -130
  8. package/dist/kalada-v1/canonicalize.cjs.map +1 -1
  9. package/dist/kalada-v1/canonicalize.d.cts +1 -0
  10. package/dist/kalada-v1/canonicalize.d.ts +1 -0
  11. package/dist/kalada-v1/canonicalize.js +56 -108
  12. package/dist/kalada-v1/canonicalize.js.map +1 -1
  13. package/dist/kalada-v1/codec.cjs +24 -0
  14. package/dist/kalada-v1/codec.cjs.map +1 -1
  15. package/dist/kalada-v1/codec.d.cts +5 -0
  16. package/dist/kalada-v1/codec.d.ts +5 -0
  17. package/dist/kalada-v1/codec.js +24 -0
  18. package/dist/kalada-v1/codec.js.map +1 -1
  19. package/dist/kalada-v1/compile.cjs +15 -1
  20. package/dist/kalada-v1/compile.cjs.map +1 -1
  21. package/dist/kalada-v1/compile.d.cts +1 -0
  22. package/dist/kalada-v1/compile.d.ts +1 -0
  23. package/dist/kalada-v1/compile.js +15 -1
  24. package/dist/kalada-v1/compile.js.map +1 -1
  25. package/dist/kalada-v1/dependencies.cjs +7 -1
  26. package/dist/kalada-v1/dependencies.cjs.map +1 -1
  27. package/dist/kalada-v1/dependencies.d.cts +1 -0
  28. package/dist/kalada-v1/dependencies.d.ts +1 -0
  29. package/dist/kalada-v1/dependencies.js +7 -1
  30. package/dist/kalada-v1/dependencies.js.map +1 -1
  31. package/dist/kalada-v1/diagnostics.cjs +6 -1
  32. package/dist/kalada-v1/diagnostics.cjs.map +1 -1
  33. package/dist/kalada-v1/diagnostics.d.cts +1 -0
  34. package/dist/kalada-v1/diagnostics.d.ts +1 -0
  35. package/dist/kalada-v1/diagnostics.js +6 -1
  36. package/dist/kalada-v1/diagnostics.js.map +1 -1
  37. package/dist/kalada-v1/evaluate.cjs +38 -3
  38. package/dist/kalada-v1/evaluate.cjs.map +1 -1
  39. package/dist/kalada-v1/evaluate.d.cts +3 -2
  40. package/dist/kalada-v1/evaluate.d.ts +3 -2
  41. package/dist/kalada-v1/evaluate.js +39 -4
  42. package/dist/kalada-v1/evaluate.js.map +1 -1
  43. package/dist/kalada-v1/factories.cjs +18 -0
  44. package/dist/kalada-v1/factories.cjs.map +1 -1
  45. package/dist/kalada-v1/factories.d.cts +8 -0
  46. package/dist/kalada-v1/factories.d.ts +8 -0
  47. package/dist/kalada-v1/factories.js +18 -0
  48. package/dist/kalada-v1/factories.js.map +1 -1
  49. package/dist/kalada-v1/index.cjs +17 -0
  50. package/dist/kalada-v1/index.d.cts +2 -1
  51. package/dist/kalada-v1/index.d.ts +2 -1
  52. package/dist/kalada-v1/index.js +1 -0
  53. package/dist/kalada-v1/limits.d.cts +1 -0
  54. package/dist/kalada-v1/limits.d.ts +1 -0
  55. package/dist/kalada-v1/schemas.cjs +29 -1
  56. package/dist/kalada-v1/schemas.cjs.map +1 -1
  57. package/dist/kalada-v1/schemas.js +29 -1
  58. package/dist/kalada-v1/schemas.js.map +1 -1
  59. package/dist/kalada-v1/temporal-evaluation.cjs +74 -0
  60. package/dist/kalada-v1/temporal-evaluation.cjs.map +1 -0
  61. package/dist/kalada-v1/temporal-evaluation.d.cts +13 -0
  62. package/dist/kalada-v1/temporal-evaluation.d.ts +13 -0
  63. package/dist/kalada-v1/temporal-evaluation.js +71 -0
  64. package/dist/kalada-v1/temporal-evaluation.js.map +1 -0
  65. package/dist/kalada-v1/temporal.cjs +42 -0
  66. package/dist/kalada-v1/temporal.cjs.map +1 -0
  67. package/dist/kalada-v1/temporal.d.cts +22 -0
  68. package/dist/kalada-v1/temporal.d.ts +22 -0
  69. package/dist/kalada-v1/temporal.js +37 -0
  70. package/dist/kalada-v1/temporal.js.map +1 -0
  71. package/dist/kalada-v1/types.d.cts +33 -4
  72. package/dist/kalada-v1/types.d.ts +33 -4
  73. package/dist/kalada-v1/values.cjs +13 -1
  74. package/dist/kalada-v1/values.cjs.map +1 -1
  75. package/dist/kalada-v1/values.d.cts +2 -1
  76. package/dist/kalada-v1/values.d.ts +2 -1
  77. package/dist/kalada-v1/values.js +13 -1
  78. package/dist/kalada-v1/values.js.map +1 -1
  79. package/package.json +1 -1
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ var diagnostics_js = require('./diagnostics.js');
4
+ var temporal_js = require('./temporal.js');
5
+
6
+ function isTemporalExpression(node) {
7
+ return node.kind === "instant" || node.kind === "duration" || node.kind === "current-instant" || node.kind === "temporal-arithmetic" || node.kind === "temporal-comparison";
8
+ }
9
+ function evaluateTemporalExpression(node, path, instant, evaluate) {
10
+ if (node.kind === "instant") return temporal_js.Instant.fromMilliseconds(node.milliseconds);
11
+ if (node.kind === "duration") return temporal_js.Duration.fromMilliseconds(node.milliseconds);
12
+ if (node.kind === "current-instant") {
13
+ if (!instant) throw new diagnostics_js.KaladaFailure("KALADA_INSTANT_REQUIRED", path);
14
+ return instant;
15
+ }
16
+ const left = temporalOperand(evaluate, node.left, [...path, "left"]);
17
+ const right = temporalOperand(evaluate, node.right, [...path, "right"]);
18
+ if (node.kind === "temporal-comparison") {
19
+ assertSameType(left, right, [...path, "right"]);
20
+ return compare(node.operator, left.milliseconds, right.milliseconds);
21
+ }
22
+ return node.operator === "add" ? add(left, right, [...path, "right"]) : subtract(left, right, [...path, "right"]);
23
+ }
24
+ function temporalOperand(evaluate, node, path) {
25
+ const value = evaluate(node, path);
26
+ if (!temporal_js.isInstant(value) && !temporal_js.isDuration(value)) mismatch(path);
27
+ return value;
28
+ }
29
+ function add(left, right, path) {
30
+ if (temporal_js.isInstant(left) && temporal_js.isDuration(right)) {
31
+ return temporal_js.Instant.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));
32
+ }
33
+ if (temporal_js.isDuration(left) && temporal_js.isDuration(right)) {
34
+ return temporal_js.Duration.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));
35
+ }
36
+ return mismatch(path);
37
+ }
38
+ function subtract(left, right, path) {
39
+ if (temporal_js.isInstant(left) && temporal_js.isInstant(right)) {
40
+ return temporal_js.Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));
41
+ }
42
+ if (temporal_js.isInstant(left) && temporal_js.isDuration(right)) {
43
+ return temporal_js.Instant.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));
44
+ }
45
+ if (temporal_js.isDuration(left) && temporal_js.isDuration(right)) {
46
+ return temporal_js.Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));
47
+ }
48
+ return mismatch(path);
49
+ }
50
+ function assertSameType(left, right, path) {
51
+ if (temporal_js.isInstant(left) && !temporal_js.isInstant(right) || temporal_js.isDuration(left) && !temporal_js.isDuration(right)) {
52
+ mismatch(path);
53
+ }
54
+ }
55
+ function compare(operator, left, right) {
56
+ if (operator === "equal") return left === right;
57
+ if (operator === "not-equal") return left !== right;
58
+ if (operator === "less-than") return left < right;
59
+ if (operator === "less-than-or-equal") return left <= right;
60
+ if (operator === "greater-than") return left > right;
61
+ return left >= right;
62
+ }
63
+ function checked(output, path) {
64
+ if (!Number.isSafeInteger(output)) throw new diagnostics_js.KaladaFailure("KALADA_TEMPORAL_OVERFLOW", path);
65
+ return Object.is(output, -0) ? 0 : output;
66
+ }
67
+ function mismatch(path) {
68
+ throw new diagnostics_js.KaladaFailure("KALADA_TEMPORAL_TYPE_MISMATCH", path);
69
+ }
70
+
71
+ exports.evaluateTemporalExpression = evaluateTemporalExpression;
72
+ exports.isTemporalExpression = isTemporalExpression;
73
+ //# sourceMappingURL=temporal-evaluation.cjs.map
74
+ //# sourceMappingURL=temporal-evaluation.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/kalada-v1/temporal-evaluation.ts"],"names":["Instant","Duration","KaladaFailure","isInstant","isDuration"],"mappings":"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","file":"temporal-evaluation.cjs","sourcesContent":["import { KaladaFailure } from \"./diagnostics.js\";\nimport type { JsonValue } from \"./json.js\";\nimport {\n Duration,\n type DurationValue,\n Instant,\n type InstantValue,\n isDuration,\n isInstant,\n} from \"./temporal.js\";\nimport type { KaladaV1Expression } from \"./types.js\";\nimport type { KaladaValue } from \"./values.js\";\n\ntype Path = readonly (string | number)[];\ntype TemporalExpression<R extends JsonValue> = Extract<\n KaladaV1Expression<R>,\n { kind: \"instant\" | \"duration\" | \"current-instant\" | `temporal-${string}` }\n>;\ntype TemporalValue = InstantValue | DurationValue;\n\nexport function isTemporalExpression<R extends JsonValue>(\n node: KaladaV1Expression<R>,\n): node is TemporalExpression<R> {\n return (\n node.kind === \"instant\" ||\n node.kind === \"duration\" ||\n node.kind === \"current-instant\" ||\n node.kind === \"temporal-arithmetic\" ||\n node.kind === \"temporal-comparison\"\n );\n}\n\nexport function evaluateTemporalExpression<R extends JsonValue>(\n node: TemporalExpression<R>,\n path: Path,\n instant: InstantValue | undefined,\n evaluate: (node: KaladaV1Expression<R>, path: Path) => KaladaValue,\n): KaladaValue {\n if (node.kind === \"instant\") return Instant.fromMilliseconds(node.milliseconds);\n if (node.kind === \"duration\") return Duration.fromMilliseconds(node.milliseconds);\n if (node.kind === \"current-instant\") {\n if (!instant) throw new KaladaFailure(\"KALADA_INSTANT_REQUIRED\", path);\n return instant;\n }\n const left = temporalOperand(evaluate, node.left, [...path, \"left\"]);\n const right = temporalOperand(evaluate, node.right, [...path, \"right\"]);\n if (node.kind === \"temporal-comparison\") {\n assertSameType(left, right, [...path, \"right\"]);\n return compare(node.operator, left.milliseconds, right.milliseconds);\n }\n return node.operator === \"add\"\n ? add(left, right, [...path, \"right\"])\n : subtract(left, right, [...path, \"right\"]);\n}\n\nfunction temporalOperand<R extends JsonValue>(\n evaluate: (node: KaladaV1Expression<R>, path: Path) => KaladaValue,\n node: KaladaV1Expression<R>,\n path: Path,\n): TemporalValue {\n const value = evaluate(node, path);\n if (!isInstant(value) && !isDuration(value)) mismatch(path);\n return value;\n}\n\nfunction add(left: TemporalValue, right: TemporalValue, path: Path): TemporalValue {\n if (isInstant(left) && isDuration(right)) {\n return Instant.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));\n }\n if (isDuration(left) && isDuration(right)) {\n return Duration.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));\n }\n return mismatch(path);\n}\n\nfunction subtract(left: TemporalValue, right: TemporalValue, path: Path): TemporalValue {\n if (isInstant(left) && isInstant(right)) {\n return Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));\n }\n if (isInstant(left) && isDuration(right)) {\n return Instant.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));\n }\n if (isDuration(left) && isDuration(right)) {\n return Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));\n }\n return mismatch(path);\n}\n\nfunction assertSameType(left: TemporalValue, right: TemporalValue, path: Path): void {\n if ((isInstant(left) && !isInstant(right)) || (isDuration(left) && !isDuration(right))) {\n mismatch(path);\n }\n}\n\nfunction compare(\n operator: Extract<KaladaV1Expression, { kind: \"temporal-comparison\" }>[\"operator\"],\n left: number,\n right: number,\n): boolean {\n if (operator === \"equal\") return left === right;\n if (operator === \"not-equal\") return left !== right;\n if (operator === \"less-than\") return left < right;\n if (operator === \"less-than-or-equal\") return left <= right;\n if (operator === \"greater-than\") return left > right;\n return left >= right;\n}\n\nfunction checked(output: number, path: Path): number {\n if (!Number.isSafeInteger(output)) throw new KaladaFailure(\"KALADA_TEMPORAL_OVERFLOW\", path);\n return Object.is(output, -0) ? 0 : output;\n}\n\nfunction mismatch(path: Path): never {\n throw new KaladaFailure(\"KALADA_TEMPORAL_TYPE_MISMATCH\", path);\n}\n"]}
@@ -0,0 +1,13 @@
1
+ import { JsonValue } from './json.cjs';
2
+ import { InstantValue } from './temporal.cjs';
3
+ import { KaladaV1Expression } from './types.cjs';
4
+ import { KaladaValue } from './values.cjs';
5
+
6
+ type Path = readonly (string | number)[];
7
+ type TemporalExpression<R extends JsonValue> = Extract<KaladaV1Expression<R>, {
8
+ kind: "instant" | "duration" | "current-instant" | `temporal-${string}`;
9
+ }>;
10
+ declare function isTemporalExpression<R extends JsonValue>(node: KaladaV1Expression<R>): node is TemporalExpression<R>;
11
+ declare function evaluateTemporalExpression<R extends JsonValue>(node: TemporalExpression<R>, path: Path, instant: InstantValue | undefined, evaluate: (node: KaladaV1Expression<R>, path: Path) => KaladaValue): KaladaValue;
12
+
13
+ export { evaluateTemporalExpression, isTemporalExpression };
@@ -0,0 +1,13 @@
1
+ import { JsonValue } from './json.js';
2
+ import { InstantValue } from './temporal.js';
3
+ import { KaladaV1Expression } from './types.js';
4
+ import { KaladaValue } from './values.js';
5
+
6
+ type Path = readonly (string | number)[];
7
+ type TemporalExpression<R extends JsonValue> = Extract<KaladaV1Expression<R>, {
8
+ kind: "instant" | "duration" | "current-instant" | `temporal-${string}`;
9
+ }>;
10
+ declare function isTemporalExpression<R extends JsonValue>(node: KaladaV1Expression<R>): node is TemporalExpression<R>;
11
+ declare function evaluateTemporalExpression<R extends JsonValue>(node: TemporalExpression<R>, path: Path, instant: InstantValue | undefined, evaluate: (node: KaladaV1Expression<R>, path: Path) => KaladaValue): KaladaValue;
12
+
13
+ export { evaluateTemporalExpression, isTemporalExpression };
@@ -0,0 +1,71 @@
1
+ import { KaladaFailure } from './diagnostics.js';
2
+ import { Instant, Duration, isInstant, isDuration } from './temporal.js';
3
+
4
+ function isTemporalExpression(node) {
5
+ return node.kind === "instant" || node.kind === "duration" || node.kind === "current-instant" || node.kind === "temporal-arithmetic" || node.kind === "temporal-comparison";
6
+ }
7
+ function evaluateTemporalExpression(node, path, instant, evaluate) {
8
+ if (node.kind === "instant") return Instant.fromMilliseconds(node.milliseconds);
9
+ if (node.kind === "duration") return Duration.fromMilliseconds(node.milliseconds);
10
+ if (node.kind === "current-instant") {
11
+ if (!instant) throw new KaladaFailure("KALADA_INSTANT_REQUIRED", path);
12
+ return instant;
13
+ }
14
+ const left = temporalOperand(evaluate, node.left, [...path, "left"]);
15
+ const right = temporalOperand(evaluate, node.right, [...path, "right"]);
16
+ if (node.kind === "temporal-comparison") {
17
+ assertSameType(left, right, [...path, "right"]);
18
+ return compare(node.operator, left.milliseconds, right.milliseconds);
19
+ }
20
+ return node.operator === "add" ? add(left, right, [...path, "right"]) : subtract(left, right, [...path, "right"]);
21
+ }
22
+ function temporalOperand(evaluate, node, path) {
23
+ const value = evaluate(node, path);
24
+ if (!isInstant(value) && !isDuration(value)) mismatch(path);
25
+ return value;
26
+ }
27
+ function add(left, right, path) {
28
+ if (isInstant(left) && isDuration(right)) {
29
+ return Instant.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));
30
+ }
31
+ if (isDuration(left) && isDuration(right)) {
32
+ return Duration.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));
33
+ }
34
+ return mismatch(path);
35
+ }
36
+ function subtract(left, right, path) {
37
+ if (isInstant(left) && isInstant(right)) {
38
+ return Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));
39
+ }
40
+ if (isInstant(left) && isDuration(right)) {
41
+ return Instant.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));
42
+ }
43
+ if (isDuration(left) && isDuration(right)) {
44
+ return Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));
45
+ }
46
+ return mismatch(path);
47
+ }
48
+ function assertSameType(left, right, path) {
49
+ if (isInstant(left) && !isInstant(right) || isDuration(left) && !isDuration(right)) {
50
+ mismatch(path);
51
+ }
52
+ }
53
+ function compare(operator, left, right) {
54
+ if (operator === "equal") return left === right;
55
+ if (operator === "not-equal") return left !== right;
56
+ if (operator === "less-than") return left < right;
57
+ if (operator === "less-than-or-equal") return left <= right;
58
+ if (operator === "greater-than") return left > right;
59
+ return left >= right;
60
+ }
61
+ function checked(output, path) {
62
+ if (!Number.isSafeInteger(output)) throw new KaladaFailure("KALADA_TEMPORAL_OVERFLOW", path);
63
+ return Object.is(output, -0) ? 0 : output;
64
+ }
65
+ function mismatch(path) {
66
+ throw new KaladaFailure("KALADA_TEMPORAL_TYPE_MISMATCH", path);
67
+ }
68
+
69
+ export { evaluateTemporalExpression, isTemporalExpression };
70
+ //# sourceMappingURL=temporal-evaluation.js.map
71
+ //# sourceMappingURL=temporal-evaluation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/kalada-v1/temporal-evaluation.ts"],"names":[],"mappings":";;;AAoBO,SAAS,qBACd,IAAA,EAC+B;AAC/B,EAAA,OACE,IAAA,CAAK,IAAA,KAAS,SAAA,IACd,IAAA,CAAK,IAAA,KAAS,UAAA,IACd,IAAA,CAAK,IAAA,KAAS,iBAAA,IACd,IAAA,CAAK,IAAA,KAAS,qBAAA,IACd,KAAK,IAAA,KAAS,qBAAA;AAElB;AAEO,SAAS,0BAAA,CACd,IAAA,EACA,IAAA,EACA,OAAA,EACA,QAAA,EACa;AACb,EAAA,IAAI,KAAK,IAAA,KAAS,SAAA,SAAkB,OAAA,CAAQ,gBAAA,CAAiB,KAAK,YAAY,CAAA;AAC9E,EAAA,IAAI,KAAK,IAAA,KAAS,UAAA,SAAmB,QAAA,CAAS,gBAAA,CAAiB,KAAK,YAAY,CAAA;AAChF,EAAA,IAAI,IAAA,CAAK,SAAS,iBAAA,EAAmB;AACnC,IAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,aAAA,CAAc,2BAA2B,IAAI,CAAA;AACrE,IAAA,OAAO,OAAA;AAAA,EACT;AACA,EAAA,MAAM,IAAA,GAAO,gBAAgB,QAAA,EAAU,IAAA,CAAK,MAAM,CAAC,GAAG,IAAA,EAAM,MAAM,CAAC,CAAA;AACnE,EAAA,MAAM,KAAA,GAAQ,gBAAgB,QAAA,EAAU,IAAA,CAAK,OAAO,CAAC,GAAG,IAAA,EAAM,OAAO,CAAC,CAAA;AACtE,EAAA,IAAI,IAAA,CAAK,SAAS,qBAAA,EAAuB;AACvC,IAAA,cAAA,CAAe,MAAM,KAAA,EAAO,CAAC,GAAG,IAAA,EAAM,OAAO,CAAC,CAAA;AAC9C,IAAA,OAAO,QAAQ,IAAA,CAAK,QAAA,EAAU,IAAA,CAAK,YAAA,EAAc,MAAM,YAAY,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,KAAK,QAAA,KAAa,KAAA,GACrB,IAAI,IAAA,EAAM,KAAA,EAAO,CAAC,GAAG,IAAA,EAAM,OAAO,CAAC,CAAA,GACnC,SAAS,IAAA,EAAM,KAAA,EAAO,CAAC,GAAG,IAAA,EAAM,OAAO,CAAC,CAAA;AAC9C;AAEA,SAAS,eAAA,CACP,QAAA,EACA,IAAA,EACA,IAAA,EACe;AACf,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,IAAA,EAAM,IAAI,CAAA;AACjC,EAAA,IAAI,CAAC,UAAU,KAAK,CAAA,IAAK,CAAC,UAAA,CAAW,KAAK,CAAA,EAAG,QAAA,CAAS,IAAI,CAAA;AAC1D,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,GAAA,CAAI,IAAA,EAAqB,KAAA,EAAsB,IAAA,EAA2B;AACjF,EAAA,IAAI,SAAA,CAAU,IAAI,CAAA,IAAK,UAAA,CAAW,KAAK,CAAA,EAAG;AACxC,IAAA,OAAO,OAAA,CAAQ,iBAAiB,OAAA,CAAQ,IAAA,CAAK,eAAe,KAAA,CAAM,YAAA,EAAc,IAAI,CAAC,CAAA;AAAA,EACvF;AACA,EAAA,IAAI,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,KAAK,CAAA,EAAG;AACzC,IAAA,OAAO,QAAA,CAAS,iBAAiB,OAAA,CAAQ,IAAA,CAAK,eAAe,KAAA,CAAM,YAAA,EAAc,IAAI,CAAC,CAAA;AAAA,EACxF;AACA,EAAA,OAAO,SAAS,IAAI,CAAA;AACtB;AAEA,SAAS,QAAA,CAAS,IAAA,EAAqB,KAAA,EAAsB,IAAA,EAA2B;AACtF,EAAA,IAAI,SAAA,CAAU,IAAI,CAAA,IAAK,SAAA,CAAU,KAAK,CAAA,EAAG;AACvC,IAAA,OAAO,QAAA,CAAS,iBAAiB,OAAA,CAAQ,IAAA,CAAK,eAAe,KAAA,CAAM,YAAA,EAAc,IAAI,CAAC,CAAA;AAAA,EACxF;AACA,EAAA,IAAI,SAAA,CAAU,IAAI,CAAA,IAAK,UAAA,CAAW,KAAK,CAAA,EAAG;AACxC,IAAA,OAAO,OAAA,CAAQ,iBAAiB,OAAA,CAAQ,IAAA,CAAK,eAAe,KAAA,CAAM,YAAA,EAAc,IAAI,CAAC,CAAA;AAAA,EACvF;AACA,EAAA,IAAI,UAAA,CAAW,IAAI,CAAA,IAAK,UAAA,CAAW,KAAK,CAAA,EAAG;AACzC,IAAA,OAAO,QAAA,CAAS,iBAAiB,OAAA,CAAQ,IAAA,CAAK,eAAe,KAAA,CAAM,YAAA,EAAc,IAAI,CAAC,CAAA;AAAA,EACxF;AACA,EAAA,OAAO,SAAS,IAAI,CAAA;AACtB;AAEA,SAAS,cAAA,CAAe,IAAA,EAAqB,KAAA,EAAsB,IAAA,EAAkB;AACnF,EAAA,IAAK,SAAA,CAAU,IAAI,CAAA,IAAK,CAAC,SAAA,CAAU,KAAK,CAAA,IAAO,UAAA,CAAW,IAAI,CAAA,IAAK,CAAC,UAAA,CAAW,KAAK,CAAA,EAAI;AACtF,IAAA,QAAA,CAAS,IAAI,CAAA;AAAA,EACf;AACF;AAEA,SAAS,OAAA,CACP,QAAA,EACA,IAAA,EACA,KAAA,EACS;AACT,EAAA,IAAI,QAAA,KAAa,OAAA,EAAS,OAAO,IAAA,KAAS,KAAA;AAC1C,EAAA,IAAI,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA,KAAS,KAAA;AAC9C,EAAA,IAAI,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA,GAAO,KAAA;AAC5C,EAAA,IAAI,QAAA,KAAa,oBAAA,EAAsB,OAAO,IAAA,IAAQ,KAAA;AACtD,EAAA,IAAI,QAAA,KAAa,cAAA,EAAgB,OAAO,IAAA,GAAO,KAAA;AAC/C,EAAA,OAAO,IAAA,IAAQ,KAAA;AACjB;AAEA,SAAS,OAAA,CAAQ,QAAgB,IAAA,EAAoB;AACnD,EAAA,IAAI,CAAC,OAAO,aAAA,CAAc,MAAM,GAAG,MAAM,IAAI,aAAA,CAAc,0BAAA,EAA4B,IAAI,CAAA;AAC3F,EAAA,OAAO,MAAA,CAAO,EAAA,CAAG,MAAA,EAAQ,EAAE,IAAI,CAAA,GAAI,MAAA;AACrC;AAEA,SAAS,SAAS,IAAA,EAAmB;AACnC,EAAA,MAAM,IAAI,aAAA,CAAc,+BAAA,EAAiC,IAAI,CAAA;AAC/D","file":"temporal-evaluation.js","sourcesContent":["import { KaladaFailure } from \"./diagnostics.js\";\nimport type { JsonValue } from \"./json.js\";\nimport {\n Duration,\n type DurationValue,\n Instant,\n type InstantValue,\n isDuration,\n isInstant,\n} from \"./temporal.js\";\nimport type { KaladaV1Expression } from \"./types.js\";\nimport type { KaladaValue } from \"./values.js\";\n\ntype Path = readonly (string | number)[];\ntype TemporalExpression<R extends JsonValue> = Extract<\n KaladaV1Expression<R>,\n { kind: \"instant\" | \"duration\" | \"current-instant\" | `temporal-${string}` }\n>;\ntype TemporalValue = InstantValue | DurationValue;\n\nexport function isTemporalExpression<R extends JsonValue>(\n node: KaladaV1Expression<R>,\n): node is TemporalExpression<R> {\n return (\n node.kind === \"instant\" ||\n node.kind === \"duration\" ||\n node.kind === \"current-instant\" ||\n node.kind === \"temporal-arithmetic\" ||\n node.kind === \"temporal-comparison\"\n );\n}\n\nexport function evaluateTemporalExpression<R extends JsonValue>(\n node: TemporalExpression<R>,\n path: Path,\n instant: InstantValue | undefined,\n evaluate: (node: KaladaV1Expression<R>, path: Path) => KaladaValue,\n): KaladaValue {\n if (node.kind === \"instant\") return Instant.fromMilliseconds(node.milliseconds);\n if (node.kind === \"duration\") return Duration.fromMilliseconds(node.milliseconds);\n if (node.kind === \"current-instant\") {\n if (!instant) throw new KaladaFailure(\"KALADA_INSTANT_REQUIRED\", path);\n return instant;\n }\n const left = temporalOperand(evaluate, node.left, [...path, \"left\"]);\n const right = temporalOperand(evaluate, node.right, [...path, \"right\"]);\n if (node.kind === \"temporal-comparison\") {\n assertSameType(left, right, [...path, \"right\"]);\n return compare(node.operator, left.milliseconds, right.milliseconds);\n }\n return node.operator === \"add\"\n ? add(left, right, [...path, \"right\"])\n : subtract(left, right, [...path, \"right\"]);\n}\n\nfunction temporalOperand<R extends JsonValue>(\n evaluate: (node: KaladaV1Expression<R>, path: Path) => KaladaValue,\n node: KaladaV1Expression<R>,\n path: Path,\n): TemporalValue {\n const value = evaluate(node, path);\n if (!isInstant(value) && !isDuration(value)) mismatch(path);\n return value;\n}\n\nfunction add(left: TemporalValue, right: TemporalValue, path: Path): TemporalValue {\n if (isInstant(left) && isDuration(right)) {\n return Instant.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));\n }\n if (isDuration(left) && isDuration(right)) {\n return Duration.fromMilliseconds(checked(left.milliseconds + right.milliseconds, path));\n }\n return mismatch(path);\n}\n\nfunction subtract(left: TemporalValue, right: TemporalValue, path: Path): TemporalValue {\n if (isInstant(left) && isInstant(right)) {\n return Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));\n }\n if (isInstant(left) && isDuration(right)) {\n return Instant.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));\n }\n if (isDuration(left) && isDuration(right)) {\n return Duration.fromMilliseconds(checked(left.milliseconds - right.milliseconds, path));\n }\n return mismatch(path);\n}\n\nfunction assertSameType(left: TemporalValue, right: TemporalValue, path: Path): void {\n if ((isInstant(left) && !isInstant(right)) || (isDuration(left) && !isDuration(right))) {\n mismatch(path);\n }\n}\n\nfunction compare(\n operator: Extract<KaladaV1Expression, { kind: \"temporal-comparison\" }>[\"operator\"],\n left: number,\n right: number,\n): boolean {\n if (operator === \"equal\") return left === right;\n if (operator === \"not-equal\") return left !== right;\n if (operator === \"less-than\") return left < right;\n if (operator === \"less-than-or-equal\") return left <= right;\n if (operator === \"greater-than\") return left > right;\n return left >= right;\n}\n\nfunction checked(output: number, path: Path): number {\n if (!Number.isSafeInteger(output)) throw new KaladaFailure(\"KALADA_TEMPORAL_OVERFLOW\", path);\n return Object.is(output, -0) ? 0 : output;\n}\n\nfunction mismatch(path: Path): never {\n throw new KaladaFailure(\"KALADA_TEMPORAL_TYPE_MISMATCH\", path);\n}\n"]}
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+
3
+ const instantBrands = /* @__PURE__ */ new WeakSet();
4
+ const durationBrands = /* @__PURE__ */ new WeakSet();
5
+ function milliseconds(input) {
6
+ if (!Number.isSafeInteger(input)) throw new RangeError("Milliseconds must be a safe integer.");
7
+ return Object.is(input, -0) ? 0 : input;
8
+ }
9
+ function branded(brands, value) {
10
+ Object.freeze(value);
11
+ brands.add(value);
12
+ return value;
13
+ }
14
+ const Instant = Object.freeze({
15
+ fromMilliseconds(value) {
16
+ return branded(instantBrands, {
17
+ type: "Instant",
18
+ milliseconds: milliseconds(value)
19
+ });
20
+ }
21
+ });
22
+ const Duration = Object.freeze({
23
+ fromMilliseconds(value) {
24
+ return branded(durationBrands, {
25
+ type: "Duration",
26
+ milliseconds: milliseconds(value)
27
+ });
28
+ }
29
+ });
30
+ function isInstant(value) {
31
+ return typeof value === "object" && value !== null && instantBrands.has(value);
32
+ }
33
+ function isDuration(value) {
34
+ return typeof value === "object" && value !== null && durationBrands.has(value);
35
+ }
36
+
37
+ exports.Duration = Duration;
38
+ exports.Instant = Instant;
39
+ exports.isDuration = isDuration;
40
+ exports.isInstant = isInstant;
41
+ //# sourceMappingURL=temporal.cjs.map
42
+ //# sourceMappingURL=temporal.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/kalada-v1/temporal.ts"],"names":[],"mappings":";;AAAA,MAAM,aAAA,uBAAoB,OAAA,EAAgB;AAC1C,MAAM,cAAA,uBAAqB,OAAA,EAAgB;AAiB3C,SAAS,aAAa,KAAA,EAAuB;AAC3C,EAAA,IAAI,CAAC,OAAO,aAAA,CAAc,KAAK,GAAG,MAAM,IAAI,WAAW,sCAAsC,CAAA;AAC7F,EAAA,OAAO,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,EAAE,IAAI,CAAA,GAAI,KAAA;AACpC;AAEA,SAAS,OAAA,CAA0B,QAAyB,KAAA,EAAa;AACvE,EAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AACnB,EAAA,MAAA,CAAO,IAAI,KAAK,CAAA;AAChB,EAAA,OAAO,KAAA;AACT;AAEO,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO;AAAA,EACnC,iBAAiB,KAAA,EAA6B;AAC5C,IAAA,OAAO,QAAQ,aAAA,EAAe;AAAA,MAC5B,IAAA,EAAM,SAAA;AAAA,MACN,YAAA,EAAc,aAAa,KAAK;AAAA,KACjB,CAAA;AAAA,EACnB;AACF,CAAC;AAEM,MAAM,QAAA,GAAW,OAAO,MAAA,CAAO;AAAA,EACpC,iBAAiB,KAAA,EAA8B;AAC7C,IAAA,OAAO,QAAQ,cAAA,EAAgB;AAAA,MAC7B,IAAA,EAAM,UAAA;AAAA,MACN,YAAA,EAAc,aAAa,KAAK;AAAA,KAChB,CAAA;AAAA,EACpB;AACF,CAAC;AAEM,SAAS,UAAU,KAAA,EAAuC;AAC/D,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,IAAQ,aAAA,CAAc,IAAI,KAAK,CAAA;AAC/E;AAEO,SAAS,WAAW,KAAA,EAAwC;AACjE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,IAAQ,cAAA,CAAe,IAAI,KAAK,CAAA;AAChF","file":"temporal.cjs","sourcesContent":["const instantBrands = new WeakSet<object>();\nconst durationBrands = new WeakSet<object>();\n\ndeclare const instantBrand: unique symbol;\ndeclare const durationBrand: unique symbol;\n\nexport interface InstantValue {\n readonly [instantBrand]: true;\n readonly type: \"Instant\";\n readonly milliseconds: number;\n}\n\nexport interface DurationValue {\n readonly [durationBrand]: true;\n readonly type: \"Duration\";\n readonly milliseconds: number;\n}\n\nfunction milliseconds(input: number): number {\n if (!Number.isSafeInteger(input)) throw new RangeError(\"Milliseconds must be a safe integer.\");\n return Object.is(input, -0) ? 0 : input;\n}\n\nfunction branded<T extends object>(brands: WeakSet<object>, value: T): T {\n Object.freeze(value);\n brands.add(value);\n return value;\n}\n\nexport const Instant = Object.freeze({\n fromMilliseconds(value: number): InstantValue {\n return branded(instantBrands, {\n type: \"Instant\",\n milliseconds: milliseconds(value),\n } as InstantValue);\n },\n});\n\nexport const Duration = Object.freeze({\n fromMilliseconds(value: number): DurationValue {\n return branded(durationBrands, {\n type: \"Duration\",\n milliseconds: milliseconds(value),\n } as DurationValue);\n },\n});\n\nexport function isInstant(value: unknown): value is InstantValue {\n return typeof value === \"object\" && value !== null && instantBrands.has(value);\n}\n\nexport function isDuration(value: unknown): value is DurationValue {\n return typeof value === \"object\" && value !== null && durationBrands.has(value);\n}\n"]}
@@ -0,0 +1,22 @@
1
+ declare const instantBrand: unique symbol;
2
+ declare const durationBrand: unique symbol;
3
+ interface InstantValue {
4
+ readonly [instantBrand]: true;
5
+ readonly type: "Instant";
6
+ readonly milliseconds: number;
7
+ }
8
+ interface DurationValue {
9
+ readonly [durationBrand]: true;
10
+ readonly type: "Duration";
11
+ readonly milliseconds: number;
12
+ }
13
+ declare const Instant: Readonly<{
14
+ fromMilliseconds(value: number): InstantValue;
15
+ }>;
16
+ declare const Duration: Readonly<{
17
+ fromMilliseconds(value: number): DurationValue;
18
+ }>;
19
+ declare function isInstant(value: unknown): value is InstantValue;
20
+ declare function isDuration(value: unknown): value is DurationValue;
21
+
22
+ export { Duration, type DurationValue, Instant, type InstantValue, isDuration, isInstant };
@@ -0,0 +1,22 @@
1
+ declare const instantBrand: unique symbol;
2
+ declare const durationBrand: unique symbol;
3
+ interface InstantValue {
4
+ readonly [instantBrand]: true;
5
+ readonly type: "Instant";
6
+ readonly milliseconds: number;
7
+ }
8
+ interface DurationValue {
9
+ readonly [durationBrand]: true;
10
+ readonly type: "Duration";
11
+ readonly milliseconds: number;
12
+ }
13
+ declare const Instant: Readonly<{
14
+ fromMilliseconds(value: number): InstantValue;
15
+ }>;
16
+ declare const Duration: Readonly<{
17
+ fromMilliseconds(value: number): DurationValue;
18
+ }>;
19
+ declare function isInstant(value: unknown): value is InstantValue;
20
+ declare function isDuration(value: unknown): value is DurationValue;
21
+
22
+ export { Duration, type DurationValue, Instant, type InstantValue, isDuration, isInstant };
@@ -0,0 +1,37 @@
1
+ const instantBrands = /* @__PURE__ */ new WeakSet();
2
+ const durationBrands = /* @__PURE__ */ new WeakSet();
3
+ function milliseconds(input) {
4
+ if (!Number.isSafeInteger(input)) throw new RangeError("Milliseconds must be a safe integer.");
5
+ return Object.is(input, -0) ? 0 : input;
6
+ }
7
+ function branded(brands, value) {
8
+ Object.freeze(value);
9
+ brands.add(value);
10
+ return value;
11
+ }
12
+ const Instant = Object.freeze({
13
+ fromMilliseconds(value) {
14
+ return branded(instantBrands, {
15
+ type: "Instant",
16
+ milliseconds: milliseconds(value)
17
+ });
18
+ }
19
+ });
20
+ const Duration = Object.freeze({
21
+ fromMilliseconds(value) {
22
+ return branded(durationBrands, {
23
+ type: "Duration",
24
+ milliseconds: milliseconds(value)
25
+ });
26
+ }
27
+ });
28
+ function isInstant(value) {
29
+ return typeof value === "object" && value !== null && instantBrands.has(value);
30
+ }
31
+ function isDuration(value) {
32
+ return typeof value === "object" && value !== null && durationBrands.has(value);
33
+ }
34
+
35
+ export { Duration, Instant, isDuration, isInstant };
36
+ //# sourceMappingURL=temporal.js.map
37
+ //# sourceMappingURL=temporal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/kalada-v1/temporal.ts"],"names":[],"mappings":"AAAA,MAAM,aAAA,uBAAoB,OAAA,EAAgB;AAC1C,MAAM,cAAA,uBAAqB,OAAA,EAAgB;AAiB3C,SAAS,aAAa,KAAA,EAAuB;AAC3C,EAAA,IAAI,CAAC,OAAO,aAAA,CAAc,KAAK,GAAG,MAAM,IAAI,WAAW,sCAAsC,CAAA;AAC7F,EAAA,OAAO,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,EAAE,IAAI,CAAA,GAAI,KAAA;AACpC;AAEA,SAAS,OAAA,CAA0B,QAAyB,KAAA,EAAa;AACvE,EAAA,MAAA,CAAO,OAAO,KAAK,CAAA;AACnB,EAAA,MAAA,CAAO,IAAI,KAAK,CAAA;AAChB,EAAA,OAAO,KAAA;AACT;AAEO,MAAM,OAAA,GAAU,OAAO,MAAA,CAAO;AAAA,EACnC,iBAAiB,KAAA,EAA6B;AAC5C,IAAA,OAAO,QAAQ,aAAA,EAAe;AAAA,MAC5B,IAAA,EAAM,SAAA;AAAA,MACN,YAAA,EAAc,aAAa,KAAK;AAAA,KACjB,CAAA;AAAA,EACnB;AACF,CAAC;AAEM,MAAM,QAAA,GAAW,OAAO,MAAA,CAAO;AAAA,EACpC,iBAAiB,KAAA,EAA8B;AAC7C,IAAA,OAAO,QAAQ,cAAA,EAAgB;AAAA,MAC7B,IAAA,EAAM,UAAA;AAAA,MACN,YAAA,EAAc,aAAa,KAAK;AAAA,KAChB,CAAA;AAAA,EACpB;AACF,CAAC;AAEM,SAAS,UAAU,KAAA,EAAuC;AAC/D,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,IAAQ,aAAA,CAAc,IAAI,KAAK,CAAA;AAC/E;AAEO,SAAS,WAAW,KAAA,EAAwC;AACjE,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,IAAQ,cAAA,CAAe,IAAI,KAAK,CAAA;AAChF","file":"temporal.js","sourcesContent":["const instantBrands = new WeakSet<object>();\nconst durationBrands = new WeakSet<object>();\n\ndeclare const instantBrand: unique symbol;\ndeclare const durationBrand: unique symbol;\n\nexport interface InstantValue {\n readonly [instantBrand]: true;\n readonly type: \"Instant\";\n readonly milliseconds: number;\n}\n\nexport interface DurationValue {\n readonly [durationBrand]: true;\n readonly type: \"Duration\";\n readonly milliseconds: number;\n}\n\nfunction milliseconds(input: number): number {\n if (!Number.isSafeInteger(input)) throw new RangeError(\"Milliseconds must be a safe integer.\");\n return Object.is(input, -0) ? 0 : input;\n}\n\nfunction branded<T extends object>(brands: WeakSet<object>, value: T): T {\n Object.freeze(value);\n brands.add(value);\n return value;\n}\n\nexport const Instant = Object.freeze({\n fromMilliseconds(value: number): InstantValue {\n return branded(instantBrands, {\n type: \"Instant\",\n milliseconds: milliseconds(value),\n } as InstantValue);\n },\n});\n\nexport const Duration = Object.freeze({\n fromMilliseconds(value: number): DurationValue {\n return branded(durationBrands, {\n type: \"Duration\",\n milliseconds: milliseconds(value),\n } as DurationValue);\n },\n});\n\nexport function isInstant(value: unknown): value is InstantValue {\n return typeof value === \"object\" && value !== null && instantBrands.has(value);\n}\n\nexport function isDuration(value: unknown): value is DurationValue {\n return typeof value === \"object\" && value !== null && durationBrands.has(value);\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import { JsonValue } from './json.cjs';
2
+ import { InstantValue } from './temporal.cjs';
2
3
  import { KaladaValue } from './values.cjs';
3
4
 
4
5
  type KaladaV1Expression<R extends JsonValue = string> = {
@@ -7,7 +8,30 @@ type KaladaV1Expression<R extends JsonValue = string> = {
7
8
  } | {
8
9
  readonly kind: "ref";
9
10
  readonly ref: R;
10
- } | BindingExpression<R> | OptionExpression<R> | ResultExpression<R> | MatchExpression<R>;
11
+ } | BindingExpression<R> | OptionExpression<R> | ResultExpression<R> | MatchExpression<R> | InstantExpression | DurationExpression | CurrentInstantExpression | TemporalArithmeticExpression<R> | TemporalComparisonExpression<R>;
12
+ interface InstantExpression {
13
+ readonly kind: "instant";
14
+ readonly milliseconds: number;
15
+ }
16
+ interface DurationExpression {
17
+ readonly kind: "duration";
18
+ readonly milliseconds: number;
19
+ }
20
+ interface CurrentInstantExpression {
21
+ readonly kind: "current-instant";
22
+ }
23
+ interface TemporalArithmeticExpression<R extends JsonValue> {
24
+ readonly kind: "temporal-arithmetic";
25
+ readonly operator: "add" | "subtract";
26
+ readonly left: KaladaV1Expression<R>;
27
+ readonly right: KaladaV1Expression<R>;
28
+ }
29
+ interface TemporalComparisonExpression<R extends JsonValue> {
30
+ readonly kind: "temporal-comparison";
31
+ readonly operator: "equal" | "not-equal" | "less-than" | "less-than-or-equal" | "greater-than" | "greater-than-or-equal";
32
+ readonly left: KaladaV1Expression<R>;
33
+ readonly right: KaladaV1Expression<R>;
34
+ }
11
35
  interface BindingExpression<R extends JsonValue> {
12
36
  readonly kind: "binding";
13
37
  readonly name: string;
@@ -44,7 +68,7 @@ interface KaladaV1Program<R extends JsonValue = string> {
44
68
  readonly profile: "kalada-v1";
45
69
  readonly expression: KaladaV1Expression<R>;
46
70
  }
47
- type KaladaV1DiagnosticCode = "KALADA_INVALID_INPUT" | "KALADA_LIMIT_EXCEEDED" | "KALADA_INVALID_REFERENCE" | "KALADA_MATCH_MISSING_ARM" | "KALADA_MATCH_DUPLICATE_ARM" | "KALADA_MATCH_UNKNOWN_ARM" | "KALADA_MATCH_UNREACHABLE_ARM" | "KALADA_MATCH_TYPE_MISMATCH" | "KALADA_REFERENCE_ERROR" | "KALADA_REFERENCE_MISSING" | "KALADA_REFERENCE_DENIED" | "KALADA_ASYNC_UNSUPPORTED" | "KALADA_INVALID_RESULT" | "KALADA_EVALUATION_LIMIT";
71
+ type KaladaV1DiagnosticCode = "KALADA_INVALID_INPUT" | "KALADA_LIMIT_EXCEEDED" | "KALADA_INVALID_REFERENCE" | "KALADA_MATCH_MISSING_ARM" | "KALADA_MATCH_DUPLICATE_ARM" | "KALADA_MATCH_UNKNOWN_ARM" | "KALADA_MATCH_UNREACHABLE_ARM" | "KALADA_MATCH_TYPE_MISMATCH" | "KALADA_REFERENCE_ERROR" | "KALADA_REFERENCE_MISSING" | "KALADA_REFERENCE_DENIED" | "KALADA_ASYNC_UNSUPPORTED" | "KALADA_INVALID_RESULT" | "KALADA_EVALUATION_LIMIT" | "KALADA_INSTANT_REQUIRED" | "KALADA_TEMPORAL_TYPE_MISMATCH" | "KALADA_TEMPORAL_OVERFLOW" | "KALADA_CLOCK_ERROR" | "KALADA_INVALID_CLOCK";
48
72
  interface KaladaV1Diagnostic {
49
73
  readonly code: KaladaV1DiagnosticCode;
50
74
  readonly path: readonly (string | number)[];
@@ -82,10 +106,15 @@ type KaladaV1Resolution = {
82
106
  readonly reason?: "missing" | "denied";
83
107
  };
84
108
  type KaladaV1Resolver<R extends JsonValue> = (reference: R) => KaladaV1Resolution;
109
+ interface KaladaV1EvaluationInputs {
110
+ readonly instant?: InstantValue;
111
+ }
112
+ type KaladaV1Clock = () => InstantValue;
85
113
  interface CompiledKaladaV1Program<R extends JsonValue> {
86
114
  readonly program: KaladaV1Program<R>;
87
115
  readonly dependencies: readonly R[];
88
- evaluate(resolve: KaladaV1Resolver<R>): KaladaV1Outcome<KaladaValue>;
116
+ evaluate(resolve: KaladaV1Resolver<R>, inputs?: KaladaV1EvaluationInputs): KaladaV1Outcome<KaladaValue>;
117
+ evaluateWithClock(resolve: KaladaV1Resolver<R>, clock: KaladaV1Clock): KaladaV1Outcome<KaladaValue>;
89
118
  }
90
119
 
91
- export type { BindingExpression, CompiledKaladaV1Program, KaladaV1Diagnostic, KaladaV1DiagnosticCode, KaladaV1Expression, KaladaV1Limits, KaladaV1Options, KaladaV1Outcome, KaladaV1Program, KaladaV1ReferenceCodec, KaladaV1Resolution, KaladaV1Resolver, MatchArm, MatchExpression, OptionExpression, ResultExpression };
120
+ export type { BindingExpression, CompiledKaladaV1Program, CurrentInstantExpression, DurationExpression, InstantExpression, KaladaV1Clock, KaladaV1Diagnostic, KaladaV1DiagnosticCode, KaladaV1EvaluationInputs, KaladaV1Expression, KaladaV1Limits, KaladaV1Options, KaladaV1Outcome, KaladaV1Program, KaladaV1ReferenceCodec, KaladaV1Resolution, KaladaV1Resolver, MatchArm, MatchExpression, OptionExpression, ResultExpression, TemporalArithmeticExpression, TemporalComparisonExpression };
@@ -1,4 +1,5 @@
1
1
  import { JsonValue } from './json.js';
2
+ import { InstantValue } from './temporal.js';
2
3
  import { KaladaValue } from './values.js';
3
4
 
4
5
  type KaladaV1Expression<R extends JsonValue = string> = {
@@ -7,7 +8,30 @@ type KaladaV1Expression<R extends JsonValue = string> = {
7
8
  } | {
8
9
  readonly kind: "ref";
9
10
  readonly ref: R;
10
- } | BindingExpression<R> | OptionExpression<R> | ResultExpression<R> | MatchExpression<R>;
11
+ } | BindingExpression<R> | OptionExpression<R> | ResultExpression<R> | MatchExpression<R> | InstantExpression | DurationExpression | CurrentInstantExpression | TemporalArithmeticExpression<R> | TemporalComparisonExpression<R>;
12
+ interface InstantExpression {
13
+ readonly kind: "instant";
14
+ readonly milliseconds: number;
15
+ }
16
+ interface DurationExpression {
17
+ readonly kind: "duration";
18
+ readonly milliseconds: number;
19
+ }
20
+ interface CurrentInstantExpression {
21
+ readonly kind: "current-instant";
22
+ }
23
+ interface TemporalArithmeticExpression<R extends JsonValue> {
24
+ readonly kind: "temporal-arithmetic";
25
+ readonly operator: "add" | "subtract";
26
+ readonly left: KaladaV1Expression<R>;
27
+ readonly right: KaladaV1Expression<R>;
28
+ }
29
+ interface TemporalComparisonExpression<R extends JsonValue> {
30
+ readonly kind: "temporal-comparison";
31
+ readonly operator: "equal" | "not-equal" | "less-than" | "less-than-or-equal" | "greater-than" | "greater-than-or-equal";
32
+ readonly left: KaladaV1Expression<R>;
33
+ readonly right: KaladaV1Expression<R>;
34
+ }
11
35
  interface BindingExpression<R extends JsonValue> {
12
36
  readonly kind: "binding";
13
37
  readonly name: string;
@@ -44,7 +68,7 @@ interface KaladaV1Program<R extends JsonValue = string> {
44
68
  readonly profile: "kalada-v1";
45
69
  readonly expression: KaladaV1Expression<R>;
46
70
  }
47
- type KaladaV1DiagnosticCode = "KALADA_INVALID_INPUT" | "KALADA_LIMIT_EXCEEDED" | "KALADA_INVALID_REFERENCE" | "KALADA_MATCH_MISSING_ARM" | "KALADA_MATCH_DUPLICATE_ARM" | "KALADA_MATCH_UNKNOWN_ARM" | "KALADA_MATCH_UNREACHABLE_ARM" | "KALADA_MATCH_TYPE_MISMATCH" | "KALADA_REFERENCE_ERROR" | "KALADA_REFERENCE_MISSING" | "KALADA_REFERENCE_DENIED" | "KALADA_ASYNC_UNSUPPORTED" | "KALADA_INVALID_RESULT" | "KALADA_EVALUATION_LIMIT";
71
+ type KaladaV1DiagnosticCode = "KALADA_INVALID_INPUT" | "KALADA_LIMIT_EXCEEDED" | "KALADA_INVALID_REFERENCE" | "KALADA_MATCH_MISSING_ARM" | "KALADA_MATCH_DUPLICATE_ARM" | "KALADA_MATCH_UNKNOWN_ARM" | "KALADA_MATCH_UNREACHABLE_ARM" | "KALADA_MATCH_TYPE_MISMATCH" | "KALADA_REFERENCE_ERROR" | "KALADA_REFERENCE_MISSING" | "KALADA_REFERENCE_DENIED" | "KALADA_ASYNC_UNSUPPORTED" | "KALADA_INVALID_RESULT" | "KALADA_EVALUATION_LIMIT" | "KALADA_INSTANT_REQUIRED" | "KALADA_TEMPORAL_TYPE_MISMATCH" | "KALADA_TEMPORAL_OVERFLOW" | "KALADA_CLOCK_ERROR" | "KALADA_INVALID_CLOCK";
48
72
  interface KaladaV1Diagnostic {
49
73
  readonly code: KaladaV1DiagnosticCode;
50
74
  readonly path: readonly (string | number)[];
@@ -82,10 +106,15 @@ type KaladaV1Resolution = {
82
106
  readonly reason?: "missing" | "denied";
83
107
  };
84
108
  type KaladaV1Resolver<R extends JsonValue> = (reference: R) => KaladaV1Resolution;
109
+ interface KaladaV1EvaluationInputs {
110
+ readonly instant?: InstantValue;
111
+ }
112
+ type KaladaV1Clock = () => InstantValue;
85
113
  interface CompiledKaladaV1Program<R extends JsonValue> {
86
114
  readonly program: KaladaV1Program<R>;
87
115
  readonly dependencies: readonly R[];
88
- evaluate(resolve: KaladaV1Resolver<R>): KaladaV1Outcome<KaladaValue>;
116
+ evaluate(resolve: KaladaV1Resolver<R>, inputs?: KaladaV1EvaluationInputs): KaladaV1Outcome<KaladaValue>;
117
+ evaluateWithClock(resolve: KaladaV1Resolver<R>, clock: KaladaV1Clock): KaladaV1Outcome<KaladaValue>;
89
118
  }
90
119
 
91
- export type { BindingExpression, CompiledKaladaV1Program, KaladaV1Diagnostic, KaladaV1DiagnosticCode, KaladaV1Expression, KaladaV1Limits, KaladaV1Options, KaladaV1Outcome, KaladaV1Program, KaladaV1ReferenceCodec, KaladaV1Resolution, KaladaV1Resolver, MatchArm, MatchExpression, OptionExpression, ResultExpression };
120
+ export type { BindingExpression, CompiledKaladaV1Program, CurrentInstantExpression, DurationExpression, InstantExpression, KaladaV1Clock, KaladaV1Diagnostic, KaladaV1DiagnosticCode, KaladaV1EvaluationInputs, KaladaV1Expression, KaladaV1Limits, KaladaV1Options, KaladaV1Outcome, KaladaV1Program, KaladaV1ReferenceCodec, KaladaV1Resolution, KaladaV1Resolver, MatchArm, MatchExpression, OptionExpression, ResultExpression, TemporalArithmeticExpression, TemporalComparisonExpression };
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var json_js = require('./json.js');
4
+ var temporal_js = require('./temporal.js');
4
5
 
5
6
  const optionBrands = /* @__PURE__ */ new WeakSet();
6
7
  const resultBrands = /* @__PURE__ */ new WeakSet();
@@ -15,7 +16,7 @@ function branded(brand, value) {
15
16
  return value;
16
17
  }
17
18
  function snapshot(value) {
18
- if (isOption(value) || isResult(value)) return value;
19
+ if (isOption(value) || isResult(value) || temporal_js.isInstant(value) || temporal_js.isDuration(value)) return value;
19
20
  return json_js.cloneJson(value, DEFAULT_VALUE_LIMITS);
20
21
  }
21
22
  const NONE = branded(optionBrands, { type: "Option", variant: "none" });
@@ -54,6 +55,10 @@ function isResult(value) {
54
55
  return typeof value === "object" && value !== null && resultBrands.has(value);
55
56
  }
56
57
  function equalKaladaValues(left, right) {
58
+ if (temporal_js.isInstant(left) || temporal_js.isInstant(right))
59
+ return temporal_js.isInstant(left) && temporal_js.isInstant(right) && left.milliseconds === right.milliseconds;
60
+ if (temporal_js.isDuration(left) || temporal_js.isDuration(right))
61
+ return temporal_js.isDuration(left) && temporal_js.isDuration(right) && left.milliseconds === right.milliseconds;
57
62
  if (isOption(left) || isOption(right)) return equalOptions(left, right);
58
63
  if (isResult(left) || isResult(right)) return equalResults(left, right);
59
64
  return json_js.deepEqualJson(left, right);
@@ -72,6 +77,10 @@ function validateKaladaValueLimits(value, limits) {
72
77
  current = current.value;
73
78
  depth += 1;
74
79
  }
80
+ if (temporal_js.isInstant(current) || temporal_js.isDuration(current)) {
81
+ validateTemporalLeaf(depth, nodes, limits);
82
+ return;
83
+ }
75
84
  const remainingDepth = limits.maxDepth - depth;
76
85
  if (remainingDepth < 0) throw new RangeError("limit");
77
86
  json_js.cloneJsonWithStats(current, {
@@ -80,6 +89,9 @@ function validateKaladaValueLimits(value, limits) {
80
89
  maxStringLength: limits.maxStringLength
81
90
  });
82
91
  }
92
+ function validateTemporalLeaf(depth, nodes, limits) {
93
+ if (depth > limits.maxDepth || nodes + 1 > limits.maxNodes) throw new RangeError("limit");
94
+ }
83
95
  function equalOptions(left, right) {
84
96
  if (!isOption(left) || !isOption(right) || left.variant !== right.variant) return false;
85
97
  if (left.variant === "none" || right.variant === "none") return true;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/kalada-v1/values.ts"],"names":["cloneJson","deepEqualJson","cloneJsonWithStats"],"mappings":"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","file":"values.cjs","sourcesContent":["import { cloneJson, cloneJsonWithStats, deepEqualJson, type JsonValue } from \"./json.js\";\n\nexport type KaladaValue = JsonValue | OptionValue | ResultValue;\nexport type OptionValue = SomeValue | NoneValue;\nexport type ResultValue = OkValue | ErrValue;\n\ndeclare const optionBrand: unique symbol;\ndeclare const resultBrand: unique symbol;\n\nexport interface SomeValue {\n readonly [optionBrand]: true;\n readonly type: \"Option\";\n readonly variant: \"some\";\n readonly value: KaladaValue;\n}\n\nexport interface NoneValue {\n readonly [optionBrand]: true;\n readonly type: \"Option\";\n readonly variant: \"none\";\n}\n\nexport interface OkValue {\n readonly [resultBrand]: true;\n readonly type: \"Result\";\n readonly variant: \"ok\";\n readonly value: KaladaValue;\n}\n\nexport interface ErrValue {\n readonly [resultBrand]: true;\n readonly type: \"Result\";\n readonly variant: \"err\";\n readonly value: KaladaValue;\n}\n\nconst optionBrands = new WeakSet<object>();\nconst resultBrands = new WeakSet<object>();\nconst DEFAULT_VALUE_LIMITS = Object.freeze({\n maxDepth: 64,\n maxNodes: 10_000,\n maxStringLength: 10_000,\n});\n\nfunction branded<T extends object>(brand: WeakSet<object>, value: T): T {\n Object.freeze(value);\n brand.add(value);\n return value;\n}\n\nfunction snapshot(value: KaladaValue): KaladaValue {\n if (isOption(value) || isResult(value)) return value;\n return cloneJson(value, DEFAULT_VALUE_LIMITS);\n}\n\nconst NONE = branded(optionBrands, { type: \"Option\", variant: \"none\" } as unknown as NoneValue);\n\nexport const Option = Object.freeze({\n some(value: KaladaValue): SomeValue {\n return branded(optionBrands, {\n type: \"Option\",\n variant: \"some\",\n value: snapshot(value),\n } as unknown as SomeValue);\n },\n none(): NoneValue {\n return NONE;\n },\n});\n\nexport const Result = Object.freeze({\n ok(value: KaladaValue): OkValue {\n return branded(resultBrands, {\n type: \"Result\",\n variant: \"ok\",\n value: snapshot(value),\n } as unknown as OkValue);\n },\n err(value: KaladaValue): ErrValue {\n return branded(resultBrands, {\n type: \"Result\",\n variant: \"err\",\n value: snapshot(value),\n } as unknown as ErrValue);\n },\n});\n\nexport function isOption(value: unknown): value is OptionValue {\n return typeof value === \"object\" && value !== null && optionBrands.has(value);\n}\n\nexport function isResult(value: unknown): value is ResultValue {\n return typeof value === \"object\" && value !== null && resultBrands.has(value);\n}\n\nexport function equalKaladaValues(left: KaladaValue, right: KaladaValue): boolean {\n if (isOption(left) || isOption(right)) return equalOptions(left, right);\n if (isResult(left) || isResult(right)) return equalResults(left, right);\n return deepEqualJson(left, right);\n}\n\nexport function validateKaladaValueLimits(\n value: KaladaValue,\n limits: {\n readonly maxDepth: number;\n readonly maxNodes: number;\n readonly maxStringLength: number;\n },\n): void {\n const seen = new WeakSet<object>();\n let current = value;\n let depth = 0;\n let nodes = 0;\n while (isOption(current) || isResult(current)) {\n nodes += 1;\n if (depth > limits.maxDepth || nodes > limits.maxNodes) throw new RangeError(\"limit\");\n if (seen.has(current)) throw new TypeError(\"cycle\");\n seen.add(current);\n if (isOption(current) && current.variant === \"none\") return;\n current = current.value;\n depth += 1;\n }\n const remainingDepth = limits.maxDepth - depth;\n if (remainingDepth < 0) throw new RangeError(\"limit\");\n cloneJsonWithStats(current, {\n maxDepth: remainingDepth,\n maxNodes: limits.maxNodes - nodes,\n maxStringLength: limits.maxStringLength,\n });\n}\n\nfunction equalOptions(left: KaladaValue, right: KaladaValue): boolean {\n if (!isOption(left) || !isOption(right) || left.variant !== right.variant) return false;\n if (left.variant === \"none\" || right.variant === \"none\") return true;\n return equalKaladaValues(left.value, right.value);\n}\n\nfunction equalResults(left: KaladaValue, right: KaladaValue): boolean {\n if (!isResult(left) || !isResult(right) || left.variant !== right.variant) return false;\n return equalKaladaValues(left.value, right.value);\n}\n"]}
1
+ {"version":3,"sources":["../../src/kalada-v1/values.ts"],"names":["isInstant","isDuration","cloneJson","deepEqualJson","cloneJsonWithStats"],"mappings":"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","file":"values.cjs","sourcesContent":["import { cloneJson, cloneJsonWithStats, deepEqualJson, type JsonValue } from \"./json.js\";\nimport { type DurationValue, type InstantValue, isDuration, isInstant } from \"./temporal.js\";\n\nexport type KaladaValue = JsonValue | OptionValue | ResultValue | InstantValue | DurationValue;\nexport type OptionValue = SomeValue | NoneValue;\nexport type ResultValue = OkValue | ErrValue;\n\ndeclare const optionBrand: unique symbol;\ndeclare const resultBrand: unique symbol;\n\nexport interface SomeValue {\n readonly [optionBrand]: true;\n readonly type: \"Option\";\n readonly variant: \"some\";\n readonly value: KaladaValue;\n}\n\nexport interface NoneValue {\n readonly [optionBrand]: true;\n readonly type: \"Option\";\n readonly variant: \"none\";\n}\n\nexport interface OkValue {\n readonly [resultBrand]: true;\n readonly type: \"Result\";\n readonly variant: \"ok\";\n readonly value: KaladaValue;\n}\n\nexport interface ErrValue {\n readonly [resultBrand]: true;\n readonly type: \"Result\";\n readonly variant: \"err\";\n readonly value: KaladaValue;\n}\n\nconst optionBrands = new WeakSet<object>();\nconst resultBrands = new WeakSet<object>();\nconst DEFAULT_VALUE_LIMITS = Object.freeze({\n maxDepth: 64,\n maxNodes: 10_000,\n maxStringLength: 10_000,\n});\n\nfunction branded<T extends object>(brand: WeakSet<object>, value: T): T {\n Object.freeze(value);\n brand.add(value);\n return value;\n}\n\nfunction snapshot(value: KaladaValue): KaladaValue {\n if (isOption(value) || isResult(value) || isInstant(value) || isDuration(value)) return value;\n return cloneJson(value, DEFAULT_VALUE_LIMITS);\n}\n\nconst NONE = branded(optionBrands, { type: \"Option\", variant: \"none\" } as unknown as NoneValue);\n\nexport const Option = Object.freeze({\n some(value: KaladaValue): SomeValue {\n return branded(optionBrands, {\n type: \"Option\",\n variant: \"some\",\n value: snapshot(value),\n } as unknown as SomeValue);\n },\n none(): NoneValue {\n return NONE;\n },\n});\n\nexport const Result = Object.freeze({\n ok(value: KaladaValue): OkValue {\n return branded(resultBrands, {\n type: \"Result\",\n variant: \"ok\",\n value: snapshot(value),\n } as unknown as OkValue);\n },\n err(value: KaladaValue): ErrValue {\n return branded(resultBrands, {\n type: \"Result\",\n variant: \"err\",\n value: snapshot(value),\n } as unknown as ErrValue);\n },\n});\n\nexport function isOption(value: unknown): value is OptionValue {\n return typeof value === \"object\" && value !== null && optionBrands.has(value);\n}\n\nexport function isResult(value: unknown): value is ResultValue {\n return typeof value === \"object\" && value !== null && resultBrands.has(value);\n}\n\nexport function equalKaladaValues(left: KaladaValue, right: KaladaValue): boolean {\n if (isInstant(left) || isInstant(right))\n return isInstant(left) && isInstant(right) && left.milliseconds === right.milliseconds;\n if (isDuration(left) || isDuration(right))\n return isDuration(left) && isDuration(right) && left.milliseconds === right.milliseconds;\n if (isOption(left) || isOption(right)) return equalOptions(left, right);\n if (isResult(left) || isResult(right)) return equalResults(left, right);\n return deepEqualJson(left, right);\n}\n\nexport function validateKaladaValueLimits(\n value: KaladaValue,\n limits: {\n readonly maxDepth: number;\n readonly maxNodes: number;\n readonly maxStringLength: number;\n },\n): void {\n const seen = new WeakSet<object>();\n let current = value;\n let depth = 0;\n let nodes = 0;\n while (isOption(current) || isResult(current)) {\n nodes += 1;\n if (depth > limits.maxDepth || nodes > limits.maxNodes) throw new RangeError(\"limit\");\n if (seen.has(current)) throw new TypeError(\"cycle\");\n seen.add(current);\n if (isOption(current) && current.variant === \"none\") return;\n current = current.value;\n depth += 1;\n }\n if (isInstant(current) || isDuration(current)) {\n validateTemporalLeaf(depth, nodes, limits);\n return;\n }\n const remainingDepth = limits.maxDepth - depth;\n if (remainingDepth < 0) throw new RangeError(\"limit\");\n cloneJsonWithStats(current, {\n maxDepth: remainingDepth,\n maxNodes: limits.maxNodes - nodes,\n maxStringLength: limits.maxStringLength,\n });\n}\n\nfunction validateTemporalLeaf(\n depth: number,\n nodes: number,\n limits: { readonly maxDepth: number; readonly maxNodes: number },\n): void {\n if (depth > limits.maxDepth || nodes + 1 > limits.maxNodes) throw new RangeError(\"limit\");\n}\n\nfunction equalOptions(left: KaladaValue, right: KaladaValue): boolean {\n if (!isOption(left) || !isOption(right) || left.variant !== right.variant) return false;\n if (left.variant === \"none\" || right.variant === \"none\") return true;\n return equalKaladaValues(left.value, right.value);\n}\n\nfunction equalResults(left: KaladaValue, right: KaladaValue): boolean {\n if (!isResult(left) || !isResult(right) || left.variant !== right.variant) return false;\n return equalKaladaValues(left.value, right.value);\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { JsonValue } from './json.cjs';
2
+ import { InstantValue, DurationValue } from './temporal.cjs';
2
3
 
3
- type KaladaValue = JsonValue | OptionValue | ResultValue;
4
+ type KaladaValue = JsonValue | OptionValue | ResultValue | InstantValue | DurationValue;
4
5
  type OptionValue = SomeValue | NoneValue;
5
6
  type ResultValue = OkValue | ErrValue;
6
7
  declare const optionBrand: unique symbol;
@@ -1,6 +1,7 @@
1
1
  import { JsonValue } from './json.js';
2
+ import { InstantValue, DurationValue } from './temporal.js';
2
3
 
3
- type KaladaValue = JsonValue | OptionValue | ResultValue;
4
+ type KaladaValue = JsonValue | OptionValue | ResultValue | InstantValue | DurationValue;
4
5
  type OptionValue = SomeValue | NoneValue;
5
6
  type ResultValue = OkValue | ErrValue;
6
7
  declare const optionBrand: unique symbol;