@elaraai/east 0.0.1-beta.25 → 0.0.1-beta.27

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 (123) hide show
  1. package/dist/src/analyze.d.ts +3 -0
  2. package/dist/src/analyze.d.ts.map +1 -1
  3. package/dist/src/analyze.js +30 -9
  4. package/dist/src/analyze.js.map +1 -1
  5. package/dist/src/ast.d.ts +1 -0
  6. package/dist/src/ast.d.ts.map +1 -1
  7. package/dist/src/ast_to_ir.d.ts.map +1 -1
  8. package/dist/src/ast_to_ir.js +2 -1
  9. package/dist/src/ast_to_ir.js.map +1 -1
  10. package/dist/src/builtins.d.ts +1 -1
  11. package/dist/src/builtins.d.ts.map +1 -1
  12. package/dist/src/builtins.js +22 -0
  13. package/dist/src/builtins.js.map +1 -1
  14. package/dist/src/compile.d.ts.map +1 -1
  15. package/dist/src/compile.js +54 -3
  16. package/dist/src/compile.js.map +1 -1
  17. package/dist/src/datetime_format/types.d.ts +23 -23
  18. package/dist/src/expr/array.d.ts +8 -0
  19. package/dist/src/expr/array.d.ts.map +1 -1
  20. package/dist/src/expr/array.js +11 -0
  21. package/dist/src/expr/array.js.map +1 -1
  22. package/dist/src/expr/blob.d.ts +8 -0
  23. package/dist/src/expr/blob.d.ts.map +1 -1
  24. package/dist/src/expr/blob.js +11 -0
  25. package/dist/src/expr/blob.js.map +1 -1
  26. package/dist/src/expr/block.d.ts +179 -1
  27. package/dist/src/expr/block.d.ts.map +1 -1
  28. package/dist/src/expr/block.js +468 -1
  29. package/dist/src/expr/block.js.map +1 -1
  30. package/dist/src/expr/boolean.d.ts +8 -0
  31. package/dist/src/expr/boolean.d.ts.map +1 -1
  32. package/dist/src/expr/boolean.js +11 -0
  33. package/dist/src/expr/boolean.js.map +1 -1
  34. package/dist/src/expr/datetime.d.ts +28 -0
  35. package/dist/src/expr/datetime.d.ts.map +1 -1
  36. package/dist/src/expr/datetime.js +31 -0
  37. package/dist/src/expr/datetime.js.map +1 -1
  38. package/dist/src/expr/dict.d.ts +8 -0
  39. package/dist/src/expr/dict.d.ts.map +1 -1
  40. package/dist/src/expr/dict.js +11 -0
  41. package/dist/src/expr/dict.js.map +1 -1
  42. package/dist/src/expr/float.d.ts +46 -0
  43. package/dist/src/expr/float.d.ts.map +1 -1
  44. package/dist/src/expr/float.js +52 -0
  45. package/dist/src/expr/float.js.map +1 -1
  46. package/dist/src/expr/index.d.ts +162 -2
  47. package/dist/src/expr/index.d.ts.map +1 -1
  48. package/dist/src/expr/index.js +168 -2
  49. package/dist/src/expr/index.js.map +1 -1
  50. package/dist/src/expr/integer.d.ts +73 -0
  51. package/dist/src/expr/integer.d.ts.map +1 -1
  52. package/dist/src/expr/integer.js +52 -0
  53. package/dist/src/expr/integer.js.map +1 -1
  54. package/dist/src/expr/set.d.ts +8 -0
  55. package/dist/src/expr/set.d.ts.map +1 -1
  56. package/dist/src/expr/set.js +11 -0
  57. package/dist/src/expr/set.js.map +1 -1
  58. package/dist/src/expr/string.d.ts +28 -0
  59. package/dist/src/expr/string.d.ts.map +1 -1
  60. package/dist/src/expr/string.js +31 -0
  61. package/dist/src/expr/string.js.map +1 -1
  62. package/dist/src/expr/variant.d.ts +8 -0
  63. package/dist/src/expr/variant.d.ts.map +1 -1
  64. package/dist/src/expr/variant.js +11 -0
  65. package/dist/src/expr/variant.js.map +1 -1
  66. package/dist/src/fuzz.d.ts +36 -2
  67. package/dist/src/fuzz.d.ts.map +1 -1
  68. package/dist/src/fuzz.js +344 -77
  69. package/dist/src/fuzz.js.map +1 -1
  70. package/dist/src/index.d.ts +1 -0
  71. package/dist/src/index.d.ts.map +1 -1
  72. package/dist/src/index.js +1 -0
  73. package/dist/src/index.js.map +1 -1
  74. package/dist/src/internal.d.ts +5 -0
  75. package/dist/src/internal.d.ts.map +1 -1
  76. package/dist/src/internal.js +6 -0
  77. package/dist/src/internal.js.map +1 -1
  78. package/dist/src/ir.d.ts +1406 -1371
  79. package/dist/src/ir.d.ts.map +1 -1
  80. package/dist/src/ir.js +1 -1
  81. package/dist/src/ir.js.map +1 -1
  82. package/dist/src/patch/apply.d.ts +15 -0
  83. package/dist/src/patch/apply.d.ts.map +1 -0
  84. package/dist/src/patch/apply.js +380 -0
  85. package/dist/src/patch/apply.js.map +1 -0
  86. package/dist/src/patch/compose.d.ts +15 -0
  87. package/dist/src/patch/compose.d.ts.map +1 -0
  88. package/dist/src/patch/compose.js +480 -0
  89. package/dist/src/patch/compose.js.map +1 -0
  90. package/dist/src/patch/diff.d.ts +15 -0
  91. package/dist/src/patch/diff.d.ts.map +1 -0
  92. package/dist/src/patch/diff.js +328 -0
  93. package/dist/src/patch/diff.js.map +1 -0
  94. package/dist/src/patch/fuzz.d.ts +73 -0
  95. package/dist/src/patch/fuzz.d.ts.map +1 -0
  96. package/dist/src/patch/fuzz.js +159 -0
  97. package/dist/src/patch/fuzz.js.map +1 -0
  98. package/dist/src/patch/index.d.ts +18 -0
  99. package/dist/src/patch/index.d.ts.map +1 -0
  100. package/dist/src/patch/index.js +20 -0
  101. package/dist/src/patch/index.js.map +1 -0
  102. package/dist/src/patch/invert.d.ts +15 -0
  103. package/dist/src/patch/invert.d.ts.map +1 -0
  104. package/dist/src/patch/invert.js +302 -0
  105. package/dist/src/patch/invert.js.map +1 -0
  106. package/dist/src/patch/type_of_patch.d.ts +17 -0
  107. package/dist/src/patch/type_of_patch.d.ts.map +1 -0
  108. package/dist/src/patch/type_of_patch.js +143 -0
  109. package/dist/src/patch/type_of_patch.js.map +1 -0
  110. package/dist/src/patch/types.d.ts +166 -0
  111. package/dist/src/patch/types.d.ts.map +1 -0
  112. package/dist/src/patch/types.js +69 -0
  113. package/dist/src/patch/types.js.map +1 -0
  114. package/dist/src/platform.d.ts +6 -0
  115. package/dist/src/platform.d.ts.map +1 -1
  116. package/dist/src/serialization/csv.d.ts +17 -17
  117. package/dist/src/type_of_type.d.ts +34 -34
  118. package/dist/src/type_of_type.js +1 -1
  119. package/dist/src/type_of_type.js.map +1 -1
  120. package/dist/src/types.d.ts +8 -8
  121. package/dist/src/types.d.ts.map +1 -1
  122. package/dist/src/types.js.map +1 -1
  123. package/package.json +1 -2
@@ -23,8 +23,10 @@ import { RecursiveExpr } from "./recursive.js";
23
23
  import { createFunctionExpr, FunctionExpr } from "./function.js";
24
24
  import { valueOrExprToAst, valueOrExprToAstTyped } from "./ast.js";
25
25
  import { toEastTypeValue } from "../type_of_type.js";
26
+ import { isVariant } from "../containers/variant.js";
26
27
  import { RefExpr } from "./ref.js";
27
28
  import { AsyncFunctionExpr, createAsyncFunctionExpr } from "./asyncfunction.js";
29
+ import { PatchType } from "../patch/index.js";
28
30
  /** A factory function to help build `Expr` from AST.
29
31
  * We inject this into each concrete `Expr` type so they can create new expressions recursively, without having circular dependencies between JavaScript modules.
30
32
  */
@@ -833,6 +835,37 @@ export function greaterEqual(left, right) {
833
835
  arguments: [Expr.ast(left), rightAst],
834
836
  });
835
837
  }
838
+ // ============================================================================
839
+ // Aliases for standalone comparison functions
840
+ // ============================================================================
841
+ /** Alias for {@link equal} */
842
+ export const equals = equal;
843
+ /** Alias for {@link equal} */
844
+ export const eq = equal;
845
+ /** Alias for {@link notEqual} */
846
+ export const notEquals = notEqual;
847
+ /** Alias for {@link notEqual} */
848
+ export const ne = notEqual;
849
+ /** Alias for {@link less} */
850
+ export const lessThan = less;
851
+ /** Alias for {@link less} */
852
+ export const lt = less;
853
+ /** Alias for {@link lessEqual} */
854
+ export const lessThanOrEqual = lessEqual;
855
+ /** Alias for {@link lessEqual} */
856
+ export const lte = lessEqual;
857
+ /** Alias for {@link lessEqual} */
858
+ export const le = lessEqual;
859
+ /** Alias for {@link greater} */
860
+ export const greaterThan = greater;
861
+ /** Alias for {@link greater} */
862
+ export const gt = greater;
863
+ /** Alias for {@link greaterEqual} */
864
+ export const greaterThanOrEqual = greaterEqual;
865
+ /** Alias for {@link greaterEqual} */
866
+ export const gte = greaterEqual;
867
+ /** Alias for {@link greaterEqual} */
868
+ export const ge = greaterEqual;
836
869
  /** Test if the first value is the same object the second.
837
870
  * For mutable collections, such as arrays, this means that they are the same object in memory.
838
871
  * For immutable data types, such as integers and strings, this is equivalent to equality.
@@ -860,6 +893,77 @@ export function print(value) {
860
893
  arguments: [valueAst],
861
894
  });
862
895
  }
896
+ // ============================================================================
897
+ // Patch Operations
898
+ // ============================================================================
899
+ /** Compute the difference between two values of the same type.
900
+ * Returns a patch that, when applied to `before`, produces `after`.
901
+ */
902
+ export function diff(before, after) {
903
+ const beforeAst = Expr.ast(before);
904
+ const afterAst = Expr.ast(after);
905
+ const valueType = beforeAst.type;
906
+ const patchType = PatchType(valueType);
907
+ return fromAst({
908
+ ast_type: "Builtin",
909
+ type: patchType,
910
+ location: get_location(2),
911
+ builtin: "Diff",
912
+ type_parameters: [valueType, patchType],
913
+ arguments: [beforeAst, afterAst],
914
+ });
915
+ }
916
+ /** Apply a patch to a value, producing the modified value.
917
+ * @throws East runtime error if the patch conflicts with the value (e.g., deleting a non-existent key)
918
+ */
919
+ export function applyPatch(value, patch) {
920
+ const valueAst = Expr.ast(value);
921
+ const patchAst = Expr.ast(patch);
922
+ const valueType = valueAst.type;
923
+ const patchType = patchAst.type;
924
+ return fromAst({
925
+ ast_type: "Builtin",
926
+ type: valueType,
927
+ location: get_location(2),
928
+ builtin: "ApplyPatch",
929
+ type_parameters: [valueType, patchType],
930
+ arguments: [valueAst, patchAst],
931
+ });
932
+ }
933
+ /** Compose two patches into a single patch.
934
+ * The result is a patch that has the same effect as applying `first` then `second`.
935
+ * @throws East runtime error if the patches are incompatible (second expects different intermediate state)
936
+ */
937
+ export function composePatch(first, second, type) {
938
+ const firstAst = Expr.ast(first);
939
+ const secondAst = Expr.ast(second);
940
+ const valueType = type;
941
+ const patchType = PatchType(valueType);
942
+ return fromAst({
943
+ ast_type: "Builtin",
944
+ type: patchType,
945
+ location: get_location(2),
946
+ builtin: "ComposePatch",
947
+ type_parameters: [valueType, patchType],
948
+ arguments: [firstAst, secondAst],
949
+ });
950
+ }
951
+ /** Invert a patch, producing a patch that undoes the original.
952
+ * Applying the inverted patch to the "after" value produces the "before" value.
953
+ */
954
+ export function invertPatch(patch, type) {
955
+ const patchAst = Expr.ast(patch);
956
+ const valueType = type;
957
+ const patchType = PatchType(valueType);
958
+ return fromAst({
959
+ ast_type: "Builtin",
960
+ type: patchType,
961
+ location: get_location(2),
962
+ builtin: "InvertPatch",
963
+ type_parameters: [valueType, patchType],
964
+ arguments: [patchAst],
965
+ });
966
+ }
863
967
  /** Create a callable helper to invoke a synchronous platform function.
864
968
  *
865
969
  * Platform functions provide access to external capabilities (logging, I/O, database access, etc.)
@@ -921,6 +1025,7 @@ export function platform(name, input_types, output_type) {
921
1025
  type: output_type,
922
1026
  location: get_location(2),
923
1027
  name: name,
1028
+ type_parameters: [],
924
1029
  arguments: argAsts,
925
1030
  async: false,
926
1031
  });
@@ -1010,6 +1115,7 @@ export function asyncPlatform(name, input_types, output_type) {
1010
1115
  type: output_type,
1011
1116
  location: get_location(2),
1012
1117
  name: name,
1118
+ type_parameters: [],
1013
1119
  arguments: argAsts,
1014
1120
  async: true,
1015
1121
  });
@@ -1039,6 +1145,347 @@ export function asyncPlatform(name, input_types, output_type) {
1039
1145
  };
1040
1146
  return fn;
1041
1147
  }
1148
+ // Runtime type substitution function
1149
+ function applyTypeArgs(typeArgs, t) {
1150
+ if (typeof t === 'string') {
1151
+ const ret = typeArgs[t];
1152
+ if (ret === undefined) {
1153
+ throw new Error(`Unexpected type argument ${t}`);
1154
+ }
1155
+ return ret;
1156
+ }
1157
+ else if (t.type === "Ref") {
1158
+ return { type: "Ref", value: applyTypeArgs(typeArgs, t.value) };
1159
+ }
1160
+ else if (t.type === "Array") {
1161
+ return { type: "Array", value: applyTypeArgs(typeArgs, t.value) };
1162
+ }
1163
+ else if (t.type === "Set") {
1164
+ return { type: "Set", key: applyTypeArgs(typeArgs, t.key) };
1165
+ }
1166
+ else if (t.type === "Dict") {
1167
+ return { type: "Dict", key: applyTypeArgs(typeArgs, t.key), value: applyTypeArgs(typeArgs, t.value) };
1168
+ }
1169
+ else if (t.type === "Struct") {
1170
+ const newFields = {};
1171
+ for (const k in t.fields) {
1172
+ newFields[k] = applyTypeArgs(typeArgs, t.fields[k]);
1173
+ }
1174
+ return { type: "Struct", fields: newFields };
1175
+ }
1176
+ else if (t.type === "Variant") {
1177
+ const newCases = {};
1178
+ for (const k in t.cases) {
1179
+ newCases[k] = applyTypeArgs(typeArgs, t.cases[k]);
1180
+ }
1181
+ return { type: "Variant", cases: newCases };
1182
+ }
1183
+ else if (t.type === "Function") {
1184
+ const newInputs = t.inputs.map((inputType) => applyTypeArgs(typeArgs, inputType));
1185
+ const newOutput = applyTypeArgs(typeArgs, t.output);
1186
+ return { type: "Function", inputs: newInputs, output: newOutput };
1187
+ }
1188
+ else if (t.type === "Recursive") {
1189
+ if (t.node === undefined) {
1190
+ // RecursiveTypeMarker (self-reference) - leave alone
1191
+ return t;
1192
+ }
1193
+ return { type: "Recursive", node: applyTypeArgs(typeArgs, t.node) };
1194
+ }
1195
+ else {
1196
+ return t;
1197
+ }
1198
+ }
1199
+ /** Create a callable helper to invoke a generic (polymorphic) platform function.
1200
+ *
1201
+ * Generic platform functions allow you to define platform functions with type parameters,
1202
+ * similar to how builtins work. The type parameters are passed at call time and flow
1203
+ * through to the implementation.
1204
+ *
1205
+ * @param name - The name of the platform function
1206
+ * @param typeParams - Array of type parameter names (e.g., `["T", "U"]`)
1207
+ * @param inputs - Array of input types, can contain string placeholders like `"T"`
1208
+ * @param output - Output type, can be a string placeholder like `"T"`
1209
+ * @returns A callable function that creates Platform AST nodes when invoked
1210
+ *
1211
+ * @example
1212
+ * ```ts
1213
+ * // Define a generic log function
1214
+ * const log = East.genericPlatform(
1215
+ * "log",
1216
+ * ["T"],
1217
+ * ["T"], // Input is type parameter T
1218
+ * NullType
1219
+ * );
1220
+ *
1221
+ * // Use it in East code - type args as array, then value args
1222
+ * const myFunction = East.function([StringType], NullType, ($, s) => {
1223
+ * $(log([StringType], s));
1224
+ * });
1225
+ *
1226
+ * // Implementation receives type params as a factory
1227
+ * const platform = [
1228
+ * log.implement((T) => (value) => {
1229
+ * console.log(printFor(T)(value));
1230
+ * return null;
1231
+ * }),
1232
+ * ];
1233
+ * ```
1234
+ *
1235
+ * @example
1236
+ * ```ts
1237
+ * // Define a generic map function with 2 type parameters
1238
+ * const map = East.genericPlatform(
1239
+ * "map",
1240
+ * ["T", "U"],
1241
+ * ["T", FunctionType(["T"], "U")], // String placeholders in nested types
1242
+ * "U"
1243
+ * );
1244
+ *
1245
+ * // Call with type args array, then value arguments
1246
+ * map([StringType, IntegerType], myString, myMapperFn)
1247
+ * ```
1248
+ */
1249
+ export function genericPlatform(name, typeParams, inputs, output) {
1250
+ const numTypeParams = typeParams.length;
1251
+ const fn = (type_args, ...valueArgs) => {
1252
+ // Validate type args array
1253
+ if (!Array.isArray(type_args)) {
1254
+ throw new Error(`Generic platform function '${name}' expects type arguments as an array, ` +
1255
+ `got ${typeof type_args}`);
1256
+ }
1257
+ // Validate type args count
1258
+ if (type_args.length !== numTypeParams) {
1259
+ throw new Error(`Generic platform function '${name}' expects ${numTypeParams} type parameters, ` +
1260
+ `got ${type_args.length}`);
1261
+ }
1262
+ // Validate type args are EastTypes
1263
+ for (let i = 0; i < numTypeParams; i++) {
1264
+ const typeArg = type_args[i];
1265
+ if (!typeArg || typeof typeArg !== 'object' || !('type' in typeArg)) {
1266
+ throw new Error(`Generic platform function '${name}' expects type parameter ${i + 1} ` +
1267
+ `(${typeParams[i]}) to be an EastType`);
1268
+ }
1269
+ }
1270
+ // Build type argument map
1271
+ const typeArgMap = {};
1272
+ typeParams.forEach((param, idx) => {
1273
+ typeArgMap[param] = type_args[idx];
1274
+ });
1275
+ // Apply type substitution to get concrete input/output types
1276
+ const inputTypes = inputs.map(t => applyTypeArgs(typeArgMap, t));
1277
+ const outputType = applyTypeArgs(typeArgMap, output);
1278
+ // Validate value args count
1279
+ if (valueArgs.length !== inputTypes.length) {
1280
+ throw new Error(`Generic platform function '${name}' expects ${inputTypes.length} ` +
1281
+ `value arguments, got ${valueArgs.length}`);
1282
+ }
1283
+ // Convert value args to AST with type validation and implicit casts
1284
+ const argAsts = valueArgs.map((arg, index) => {
1285
+ const expectedType = inputTypes[index];
1286
+ let ast = valueOrExprToAstTyped(arg, expectedType);
1287
+ if (ast.type.type === "Never") {
1288
+ throw new Error(`Generic platform function ${name} argument ${index + 1} expected type ${printType(expectedType)}, got Never type`);
1289
+ }
1290
+ if (!isTypeEqual(ast.type, expectedType)) {
1291
+ if (!isSubtype(ast.type, expectedType)) {
1292
+ throw new Error(`Generic platform function ${name} argument ${index + 1} expected type ${printType(expectedType)}, got ${printType(ast.type)}`);
1293
+ }
1294
+ // Insert implicit cast
1295
+ ast = {
1296
+ ast_type: "As",
1297
+ type: expectedType,
1298
+ location: get_location(2),
1299
+ value: ast,
1300
+ };
1301
+ }
1302
+ return ast;
1303
+ });
1304
+ // Create PlatformAST with type_parameters
1305
+ return fromAst({
1306
+ ast_type: "Platform",
1307
+ type: outputType,
1308
+ location: get_location(2),
1309
+ name: name,
1310
+ type_parameters: type_args,
1311
+ arguments: argAsts,
1312
+ async: false,
1313
+ });
1314
+ };
1315
+ fn.implement = (factory) => {
1316
+ return {
1317
+ name,
1318
+ type_parameters: [...typeParams],
1319
+ inputs: [], // Computed at call time via inputsFn
1320
+ output: toEastTypeValue(NullType), // Placeholder
1321
+ inputsFn: (...tps) => {
1322
+ const typeArgMap = {};
1323
+ typeParams.forEach((param, idx) => {
1324
+ typeArgMap[param] = tps[idx];
1325
+ });
1326
+ return inputs.map(t => {
1327
+ if (typeof t === 'string')
1328
+ return typeArgMap[t];
1329
+ let result = applyTypeArgs(typeArgMap, t);
1330
+ if (!isVariant(result))
1331
+ result = toEastTypeValue(result);
1332
+ return result;
1333
+ });
1334
+ },
1335
+ outputsFn: (...tps) => {
1336
+ const typeArgMap = {};
1337
+ typeParams.forEach((param, idx) => {
1338
+ typeArgMap[param] = tps[idx];
1339
+ });
1340
+ if (typeof output === 'string')
1341
+ return typeArgMap[output];
1342
+ let result = applyTypeArgs(typeArgMap, output);
1343
+ if (!isVariant(result))
1344
+ result = toEastTypeValue(result);
1345
+ return result;
1346
+ },
1347
+ type: 'sync',
1348
+ fn: factory,
1349
+ };
1350
+ };
1351
+ return fn;
1352
+ }
1353
+ /** Create a callable helper to invoke an asynchronous generic (polymorphic) platform function.
1354
+ *
1355
+ * This is the async variant of `genericPlatform`. The implementation factory should return
1356
+ * an async function.
1357
+ *
1358
+ * @param name - The name of the platform function
1359
+ * @param typeParams - Array of type parameter names (e.g., `["T", "U"]`)
1360
+ * @param inputs - Array of input types, can contain string placeholders like `"T"`
1361
+ * @param output - Output type, can be a string placeholder like `"T"`
1362
+ * @returns A callable function that creates Platform AST nodes when invoked
1363
+ *
1364
+ * @see {@link genericPlatform} for synchronous generic platform functions
1365
+ *
1366
+ * @example
1367
+ * ```ts
1368
+ * // Define an async generic fetch function
1369
+ * const fetchAs = East.asyncGenericPlatform(
1370
+ * "fetchAs",
1371
+ * ["T"],
1372
+ * [StringType], // URL input
1373
+ * "T" // Returns parsed value of type T
1374
+ * );
1375
+ *
1376
+ * // Implementation receives type params and returns async function
1377
+ * const platform = [
1378
+ * fetchAs.implement((T) => async (url) => {
1379
+ * const response = await fetch(url);
1380
+ * return parseFor(T)(await response.text());
1381
+ * }),
1382
+ * ];
1383
+ * ```
1384
+ */
1385
+ export function asyncGenericPlatform(name, typeParams, inputs, output) {
1386
+ const numTypeParams = typeParams.length;
1387
+ const fn = (type_args, ...valueArgs) => {
1388
+ // Validate type args array
1389
+ if (!Array.isArray(type_args)) {
1390
+ throw new Error(`Generic platform function '${name}' expects type arguments as an array, ` +
1391
+ `got ${typeof type_args}`);
1392
+ }
1393
+ // Validate type args count
1394
+ if (type_args.length !== numTypeParams) {
1395
+ throw new Error(`Generic platform function '${name}' expects ${numTypeParams} type parameters, ` +
1396
+ `got ${type_args.length}`);
1397
+ }
1398
+ // Validate type args are EastTypes
1399
+ for (let i = 0; i < numTypeParams; i++) {
1400
+ const typeArg = type_args[i];
1401
+ if (!typeArg || typeof typeArg !== 'object' || !('type' in typeArg)) {
1402
+ throw new Error(`Generic platform function '${name}' expects type parameter ${i + 1} ` +
1403
+ `(${typeParams[i]}) to be an EastType`);
1404
+ }
1405
+ }
1406
+ // Build type argument map
1407
+ const typeArgMap = {};
1408
+ typeParams.forEach((param, idx) => {
1409
+ typeArgMap[param] = type_args[idx];
1410
+ });
1411
+ // Apply type substitution to get concrete input/output types
1412
+ const inputTypes = inputs.map(t => applyTypeArgs(typeArgMap, t));
1413
+ const outputType = applyTypeArgs(typeArgMap, output);
1414
+ // Validate value args count
1415
+ if (valueArgs.length !== inputTypes.length) {
1416
+ throw new Error(`Generic platform function '${name}' expects ${inputTypes.length} ` +
1417
+ `value arguments, got ${valueArgs.length}`);
1418
+ }
1419
+ // Convert value args to AST with type validation and implicit casts
1420
+ const argAsts = valueArgs.map((arg, index) => {
1421
+ const expectedType = inputTypes[index];
1422
+ let ast = valueOrExprToAstTyped(arg, expectedType);
1423
+ if (ast.type.type === "Never") {
1424
+ throw new Error(`Generic platform function ${name} argument ${index + 1} expected type ${printType(expectedType)}, got Never type`);
1425
+ }
1426
+ if (!isTypeEqual(ast.type, expectedType)) {
1427
+ if (!isSubtype(ast.type, expectedType)) {
1428
+ throw new Error(`Generic platform function ${name} argument ${index + 1} expected type ${printType(expectedType)}, got ${printType(ast.type)}`);
1429
+ }
1430
+ // Insert implicit cast
1431
+ ast = {
1432
+ ast_type: "As",
1433
+ type: expectedType,
1434
+ location: get_location(2),
1435
+ value: ast,
1436
+ };
1437
+ }
1438
+ return ast;
1439
+ });
1440
+ // Create PlatformAST with type_parameters and async: true
1441
+ return fromAst({
1442
+ ast_type: "Platform",
1443
+ type: outputType,
1444
+ location: get_location(2),
1445
+ name: name,
1446
+ type_parameters: type_args,
1447
+ arguments: argAsts,
1448
+ async: true,
1449
+ });
1450
+ };
1451
+ fn.implement = (factory) => {
1452
+ return {
1453
+ name,
1454
+ type_parameters: [...typeParams],
1455
+ inputs: [], // Computed at call time via inputsFn
1456
+ output: toEastTypeValue(NullType), // Placeholder
1457
+ inputsFn: (...tps) => {
1458
+ const typeArgMap = {};
1459
+ typeParams.forEach((param, idx) => {
1460
+ typeArgMap[param] = tps[idx];
1461
+ });
1462
+ return inputs.map(t => {
1463
+ if (typeof t === 'string')
1464
+ return typeArgMap[t];
1465
+ let result = applyTypeArgs(typeArgMap, t);
1466
+ if (!isVariant(result))
1467
+ result = toEastTypeValue(result);
1468
+ return result;
1469
+ });
1470
+ },
1471
+ outputsFn: (...tps) => {
1472
+ const typeArgMap = {};
1473
+ typeParams.forEach((param, idx) => {
1474
+ typeArgMap[param] = tps[idx];
1475
+ });
1476
+ if (typeof output === 'string')
1477
+ return typeArgMap[output];
1478
+ let result = applyTypeArgs(typeArgMap, output);
1479
+ if (!isVariant(result))
1480
+ result = toEastTypeValue(result);
1481
+ return result;
1482
+ },
1483
+ type: 'async',
1484
+ fn: factory,
1485
+ };
1486
+ };
1487
+ return fn;
1488
+ }
1042
1489
  export const BlockBuilder = (return_type) => {
1043
1490
  const statements = [];
1044
1491
  const $ = ((expr) => {
@@ -1757,6 +2204,26 @@ Object.assign(Expr, {
1757
2204
  greater,
1758
2205
  greaterEqual,
1759
2206
  is,
1760
- match: matchExpr
2207
+ match: matchExpr,
2208
+ // Comparison aliases
2209
+ equals,
2210
+ eq,
2211
+ notEquals,
2212
+ ne,
2213
+ lessThan,
2214
+ lt,
2215
+ lessThanOrEqual,
2216
+ lte,
2217
+ le,
2218
+ greaterThan,
2219
+ gt,
2220
+ greaterThanOrEqual,
2221
+ gte,
2222
+ ge,
2223
+ // Patch operations
2224
+ diff,
2225
+ applyPatch,
2226
+ composePatch,
2227
+ invertPatch,
1761
2228
  });
1762
2229
  //# sourceMappingURL=block.js.map