envio 3.12.0 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -6
- package/src/ChainFetching.res +7 -3
- package/src/ChainFetching.res.mjs +1 -1
- package/src/ChainState.res +12 -3
- package/src/ChainState.res.mjs +3 -3
- package/src/ChainState.resi +1 -1
- package/src/CrossChainState.res +1 -1
- package/src/CrossChainState.res.mjs +1 -1
- package/src/FetchState.res +51 -46
- package/src/FetchState.res.mjs +54 -36
- package/src/InMemoryTable.res +155 -67
- package/src/InMemoryTable.res.mjs +151 -60
- package/src/LoadLayer.res +57 -34
- package/src/LoadLayer.res.mjs +45 -62
- package/src/LoadLayer.resi +1 -1
- package/src/PgStorage.res +92 -62
- package/src/PgStorage.res.mjs +77 -50
- package/src/TestIndexer.res +9 -25
- package/src/TestIndexer.res.mjs +4 -3
- package/src/UserContext.res +13 -32
- package/src/UserContext.res.mjs +1 -7
- package/src/Utils.res +1 -4
- package/src/Utils.res.mjs +7 -16
- package/src/db/EntityFilter.res +487 -275
- package/src/db/EntityFilter.res.mjs +557 -309
- package/src/db/Table.res +21 -6
- package/src/db/Table.res.mjs +13 -4
- package/src/sources/BlockStore.res +7 -2
- package/src/sources/EvmHyperSyncSource.res +2 -0
- package/src/sources/EvmHyperSyncSource.res.mjs +2 -2
- package/src/sources/FuelHyperSyncSource.res +1 -0
- package/src/sources/FuelHyperSyncSource.res.mjs +1 -1
- package/src/sources/HyperSync.res +4 -0
- package/src/sources/HyperSync.res.mjs +4 -2
- package/src/sources/HyperSync.resi +1 -0
- package/src/sources/HyperSyncClient.res +3 -0
- package/src/sources/HyperSyncSSE.res +1 -1
- package/src/sources/HyperSyncSSE.res.mjs +4 -10
- package/src/sources/RpcSource.res +1 -0
- package/src/sources/RpcSource.res.mjs +1 -1
- package/src/sources/SimulateSource.res +1 -0
- package/src/sources/SimulateSource.res.mjs +1 -1
- package/src/sources/Source.res +7 -0
- package/src/sources/SourceManager.res +4 -3
- package/src/sources/SourceManager.res.mjs +2 -2
- package/src/sources/SvmHyperSyncClient.res +5 -0
- package/src/sources/SvmHyperSyncSource.res +3 -0
- package/src/sources/SvmHyperSyncSource.res.mjs +4 -2
package/src/PgStorage.res.mjs
CHANGED
|
@@ -19,6 +19,7 @@ import * as ChainState from "./ChainState.res.mjs";
|
|
|
19
19
|
import * as AddressRows from "./AddressRows.res.mjs";
|
|
20
20
|
import * as Performance from "./bindings/Performance.res.mjs";
|
|
21
21
|
import * as Persistence from "./Persistence.res.mjs";
|
|
22
|
+
import * as EntityFilter from "./db/EntityFilter.res.mjs";
|
|
22
23
|
import * as IndexCatalog from "./db/IndexCatalog.res.mjs";
|
|
23
24
|
import * as IndexManager from "./db/IndexManager.res.mjs";
|
|
24
25
|
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
@@ -301,7 +302,7 @@ function makeLoadQuery(pgSchema, tableName, condition) {
|
|
|
301
302
|
return `SELECT * FROM "` + pgSchema + `"."` + tableName + `" WHERE ` + condition + `;`;
|
|
302
303
|
}
|
|
303
304
|
|
|
304
|
-
function makeFilterCondition(filter, table, params) {
|
|
305
|
+
function makeFilterCondition(filter, table, pgSchema, params) {
|
|
305
306
|
let getQueryFieldOrThrow = fieldName => {
|
|
306
307
|
let queryField = Table.queryFields(table)[fieldName];
|
|
307
308
|
if (queryField !== undefined) {
|
|
@@ -333,39 +334,76 @@ function makeFilterCondition(filter, table, params) {
|
|
|
333
334
|
params.push(param);
|
|
334
335
|
return `$` + params.length.toString();
|
|
335
336
|
};
|
|
336
|
-
let
|
|
337
|
-
|
|
338
|
-
return `"` + queryField.pgDbFieldName + `" ` + op + ` ` + serializeParamOrThrow(queryField, fieldName, fieldValue, false);
|
|
337
|
+
let condition = {
|
|
338
|
+
contents: ""
|
|
339
339
|
};
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
let
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
340
|
+
Utils.Dict.forEachWithKey(EntityFilter.entries(filter), (operators, fieldName) => {
|
|
341
|
+
let queryField = getQueryFieldOrThrow(fieldName);
|
|
342
|
+
Utils.Dict.forEachWithKey(operators, (fieldValue, operator) => {
|
|
343
|
+
let column = `"` + queryField.pgDbFieldName + `"`;
|
|
344
|
+
let part;
|
|
345
|
+
let exit = 0;
|
|
346
|
+
switch (operator) {
|
|
347
|
+
case "_eq" :
|
|
348
|
+
if (queryField.isChainId) {
|
|
349
|
+
part = column + ` = ` + ChainId.toString(ChainId.normalizeOrThrow(fieldValue));
|
|
350
|
+
} else {
|
|
351
|
+
exit = 1;
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
case "_in" :
|
|
355
|
+
if (queryField.isArray || queryField.fieldType === "Boolean") {
|
|
356
|
+
let candidates = EntityFilter.asArray(fieldValue);
|
|
357
|
+
part = candidates.length !== 0 ? `(` + candidates.map(candidate => column + ` = ` + serializeParamOrThrow(queryField, fieldName, candidate, false)).join(" OR ") + `)` : "FALSE";
|
|
358
|
+
} else {
|
|
359
|
+
let param = serializeParamOrThrow(queryField, fieldName, fieldValue, true);
|
|
360
|
+
let match = queryField.fieldType;
|
|
361
|
+
let exit$1 = 0;
|
|
362
|
+
if (typeof match !== "object" || match.type !== "Enum") {
|
|
363
|
+
exit$1 = 2;
|
|
364
|
+
} else {
|
|
365
|
+
part = column + ` = ANY(` + param + `::TEXT[]::"` + pgSchema + `".` + match.config.name + `[])`;
|
|
366
|
+
}
|
|
367
|
+
if (exit$1 === 2) {
|
|
368
|
+
part = column + ` = ANY(` + param + `)`;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
break;
|
|
372
|
+
default:
|
|
373
|
+
exit = 1;
|
|
348
374
|
}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
375
|
+
if (exit === 1) {
|
|
376
|
+
let sqlOperator;
|
|
377
|
+
switch (operator) {
|
|
378
|
+
case "_eq" :
|
|
379
|
+
sqlOperator = "=";
|
|
380
|
+
break;
|
|
381
|
+
case "_gt" :
|
|
382
|
+
sqlOperator = ">";
|
|
383
|
+
break;
|
|
384
|
+
case "_gte" :
|
|
385
|
+
sqlOperator = ">=";
|
|
386
|
+
break;
|
|
387
|
+
case "_lt" :
|
|
388
|
+
sqlOperator = "<";
|
|
389
|
+
break;
|
|
390
|
+
case "_lte" :
|
|
391
|
+
sqlOperator = "<=";
|
|
392
|
+
break;
|
|
393
|
+
default:
|
|
394
|
+
throw {
|
|
395
|
+
RE_EXN_ID: Persistence.StorageError,
|
|
396
|
+
message: `Failed loading "` + table.tableName + `" from storage. Unknown filter operator "` + operator + `".`,
|
|
397
|
+
reason: new Error(`Unknown filter operator "` + operator + `"`),
|
|
398
|
+
Error: new Error()
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
part = column + ` ` + sqlOperator + ` ` + serializeParamOrThrow(queryField, fieldName, fieldValue, false);
|
|
361
402
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
Error: new Error()
|
|
367
|
-
};
|
|
368
|
-
}
|
|
403
|
+
condition.contents = condition.contents === "" ? part : condition.contents + " AND " + part;
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
return condition.contents;
|
|
369
407
|
}
|
|
370
408
|
|
|
371
409
|
function makeChainIdCondition(table, chainId) {
|
|
@@ -1032,16 +1070,10 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1032
1070
|
let chainIdMode = chainIdModeOpt !== undefined ? chainIdModeOpt : "int32";
|
|
1033
1071
|
let isolated = isolatedOpt !== undefined ? isolatedOpt : false;
|
|
1034
1072
|
let containerName = "envio-postgres";
|
|
1035
|
-
let psqlExecOptions_env =
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
],
|
|
1040
|
-
[
|
|
1041
|
-
"PATH",
|
|
1042
|
-
process.env.PATH
|
|
1043
|
-
]
|
|
1044
|
-
]);
|
|
1073
|
+
let psqlExecOptions_env = {
|
|
1074
|
+
PGPASSWORD: pgPassword,
|
|
1075
|
+
PATH: process.env.PATH
|
|
1076
|
+
};
|
|
1045
1077
|
let psqlExecOptions = {
|
|
1046
1078
|
env: psqlExecOptions_env
|
|
1047
1079
|
};
|
|
@@ -1222,7 +1254,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1222
1254
|
};
|
|
1223
1255
|
let loadOrThrow = async (filter, table) => {
|
|
1224
1256
|
let params = [];
|
|
1225
|
-
let condition = makeFilterCondition(filter, table, params);
|
|
1257
|
+
let condition = makeFilterCondition(filter, table, pgSchema, params);
|
|
1226
1258
|
let rows;
|
|
1227
1259
|
try {
|
|
1228
1260
|
rows = await sql.unsafe(makeLoadQuery(pgSchema, table.tableName, condition), params, {prepare: true});
|
|
@@ -1251,12 +1283,8 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1251
1283
|
let queryFields = Table.queryFields(table);
|
|
1252
1284
|
let columns = [];
|
|
1253
1285
|
let seen = new Set();
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
filter.filters.forEach(collect);
|
|
1257
|
-
return;
|
|
1258
|
-
}
|
|
1259
|
-
let match = queryFields[filter.fieldName];
|
|
1286
|
+
filters.forEach(filter => Utils.Dict.forEachWithKey(EntityFilter.entries(filter), (param, fieldName) => {
|
|
1287
|
+
let match = queryFields[fieldName];
|
|
1260
1288
|
if (match === undefined) {
|
|
1261
1289
|
return;
|
|
1262
1290
|
}
|
|
@@ -1266,8 +1294,7 @@ function make(sql, pgHost, pgSchema, pgPort, pgUser, pgDatabase, pgPassword, isH
|
|
|
1266
1294
|
columns.push(pgDbFieldName);
|
|
1267
1295
|
return;
|
|
1268
1296
|
}
|
|
1269
|
-
};
|
|
1270
|
-
filters.forEach(collect);
|
|
1297
|
+
}));
|
|
1271
1298
|
return columns;
|
|
1272
1299
|
};
|
|
1273
1300
|
let runAndVerify = async (sql, prepared) => {
|
package/src/TestIndexer.res
CHANGED
|
@@ -75,15 +75,10 @@ let handleLoad = (state: testIndexerState, ~tableName: string, ~filter: EntityFi
|
|
|
75
75
|
| None => []
|
|
76
76
|
| Some(entityConfig) =>
|
|
77
77
|
let entityDict = state.entities->Dict.get(tableName)->Option.getOr(Dict.make())
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// The store holds decoded entities and the filter carries decoded values,
|
|
83
|
-
// so compare directly (same approach as InMemoryTable) — no JSON round-trip.
|
|
84
|
-
let entityAsDict = entity->(Utils.magic: Internal.entity => dict<EntityFilter.FieldValue.t>)
|
|
85
|
-
filter->EntityFilter.matches(~entity=entityAsDict)
|
|
86
|
-
})
|
|
78
|
+
// The store holds decoded entities and the filter carries decoded values,
|
|
79
|
+
// so compare directly (same approach as InMemoryTable) — no JSON round-trip.
|
|
80
|
+
let matcher = filter->EntityFilter.makeMatcher(~table=entityConfig.table)
|
|
81
|
+
let matched = entityDict->Dict.valuesToArray->Array.filter(matcher)
|
|
87
82
|
// The chain is already fixed by the scope the load ran for, so the loaded
|
|
88
83
|
// entity is handed back in the shape the handlers see.
|
|
89
84
|
switch entityConfig.table->Table.getChainIdField {
|
|
@@ -544,23 +539,12 @@ let makeEntityGetWhere = (~state: testIndexerState, ~entityConfig: Internal.enti
|
|
|
544
539
|
`Cannot call ${entityConfig.name}.getWhere() while indexer.process() is running. ` ++ "Wait for process() to complete before accessing entities directly.",
|
|
545
540
|
)
|
|
546
541
|
}
|
|
547
|
-
let
|
|
548
|
-
filter
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
)
|
|
542
|
+
let matcher =
|
|
543
|
+
filter
|
|
544
|
+
->EntityFilter.parseOrThrow(~entityName=entityConfig.name, ~table=entityConfig.table)
|
|
545
|
+
->EntityFilter.makeMatcher(~table=entityConfig.table)
|
|
552
546
|
let entityDict = state.entities->Dict.get(entityConfig.name)->Option.getOr(Dict.make())
|
|
553
|
-
|
|
554
|
-
// matches are disjoint, so the union needs no dedup.
|
|
555
|
-
Promise.resolve(
|
|
556
|
-
entityDict
|
|
557
|
-
->Dict.valuesToArray
|
|
558
|
-
->Array.filter(entity => {
|
|
559
|
-
let entityAsDict = entity->(Utils.magic: Internal.entity => dict<EntityFilter.FieldValue.t>)
|
|
560
|
-
filters->Array.some(filter => filter->EntityFilter.matches(~entity=entityAsDict))
|
|
561
|
-
})
|
|
562
|
-
->Array.map(copyEntity),
|
|
563
|
-
)
|
|
547
|
+
Promise.resolve(entityDict->Dict.valuesToArray->Array.filter(matcher)->Array.map(copyEntity))
|
|
564
548
|
}
|
|
565
549
|
}
|
|
566
550
|
|
package/src/TestIndexer.res.mjs
CHANGED
|
@@ -56,7 +56,8 @@ function handleLoad(state, tableName, filter) {
|
|
|
56
56
|
return [];
|
|
57
57
|
}
|
|
58
58
|
let entityDict = Stdlib_Option.getOr(state.entities[tableName], {});
|
|
59
|
-
let
|
|
59
|
+
let matcher = EntityFilter.makeMatcher(filter, entityConfig.table);
|
|
60
|
+
let matched = Object.values(entityDict).filter(matcher);
|
|
60
61
|
let field = Table.getChainIdField(entityConfig.table);
|
|
61
62
|
if (field !== undefined) {
|
|
62
63
|
return matched.map(entity => {
|
|
@@ -376,9 +377,9 @@ function makeEntityGetWhere(state, entityConfig) {
|
|
|
376
377
|
if (state.processInProgress) {
|
|
377
378
|
Stdlib_JsError.throwWithMessage(`Cannot call ` + entityConfig.name + `.getWhere() while indexer.process() is running. ` + "Wait for process() to complete before accessing entities directly.");
|
|
378
379
|
}
|
|
379
|
-
let
|
|
380
|
+
let matcher = EntityFilter.makeMatcher(EntityFilter.parseOrThrow(filter, entityConfig.name, entityConfig.table), entityConfig.table);
|
|
380
381
|
let entityDict = Stdlib_Option.getOr(state.entities[entityConfig.name], {});
|
|
381
|
-
return Promise.resolve(Object.values(entityDict).filter(
|
|
382
|
+
return Promise.resolve(Object.values(entityDict).filter(matcher).map(copyEntity));
|
|
382
383
|
};
|
|
383
384
|
}
|
|
384
385
|
|
package/src/UserContext.res
CHANGED
|
@@ -122,39 +122,20 @@ type entityContextParams = {
|
|
|
122
122
|
// The handler context is always chain-scoped, so a per-chain entity resolves to
|
|
123
123
|
// the chain the handler runs on and a cross-chain one to the shared partition.
|
|
124
124
|
let entityScope = (params: entityContextParams) =>
|
|
125
|
-
params.entityConfig->InMemoryStore.entityScope(
|
|
126
|
-
~chainId=params.item->Internal.getItemChainId,
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
let getWhereHandler = (params: entityContextParams, filter: dict<dict<unknown>>) => {
|
|
130
|
-
let entityConfig = params.entityConfig
|
|
131
|
-
|
|
132
|
-
@inline
|
|
133
|
-
let loadWithFilter = filter =>
|
|
134
|
-
LoadLayer.loadByFilter(
|
|
135
|
-
~loadManager=params.loadManager,
|
|
136
|
-
~persistence=params.persistence,
|
|
137
|
-
~entityConfig,
|
|
138
|
-
~scope=params->entityScope,
|
|
139
|
-
~indexerState=params.indexerState,
|
|
140
|
-
~shouldGroup=params.isPreload,
|
|
141
|
-
~item=params.item,
|
|
142
|
-
~ecosystem=params.config.ecosystem,
|
|
143
|
-
~filter,
|
|
144
|
-
)
|
|
125
|
+
params.entityConfig->InMemoryStore.entityScope(~chainId=params.item->Internal.getItemChainId)
|
|
145
126
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
~
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
127
|
+
let getWhereHandler = (params: entityContextParams, filter: dict<dict<unknown>>) =>
|
|
128
|
+
LoadLayer.loadByFilter(
|
|
129
|
+
~loadManager=params.loadManager,
|
|
130
|
+
~persistence=params.persistence,
|
|
131
|
+
~entityConfig=params.entityConfig,
|
|
132
|
+
~scope=params->entityScope,
|
|
133
|
+
~indexerState=params.indexerState,
|
|
134
|
+
~shouldGroup=params.isPreload,
|
|
135
|
+
~item=params.item,
|
|
136
|
+
~ecosystem=params.config.ecosystem,
|
|
137
|
+
~filter,
|
|
138
|
+
)
|
|
158
139
|
|
|
159
140
|
let noopSet = (_entity: Internal.entity) => ()
|
|
160
141
|
let noopDeleteUnsafe = (_entityId: EntityId.t) => ()
|
package/src/UserContext.res.mjs
CHANGED
|
@@ -77,13 +77,7 @@ function entityScope(params) {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
function getWhereHandler(params, filter) {
|
|
80
|
-
|
|
81
|
-
let filters = EntityFilter.parseGetWhereOrThrow(filter, entityConfig.name, entityConfig.table);
|
|
82
|
-
if (filters.length !== 1) {
|
|
83
|
-
return Promise.all(filters.map(filter => LoadLayer.loadByFilter(params.loadManager, params.persistence, entityConfig, entityScope(params), params.indexerState, params.isPreload, params.item, params.config.ecosystem, filter))).then(results => results.flat());
|
|
84
|
-
} else {
|
|
85
|
-
return LoadLayer.loadByFilter(params.loadManager, params.persistence, entityConfig, entityScope(params), params.indexerState, params.isPreload, params.item, params.config.ecosystem, filters[0]);
|
|
86
|
-
}
|
|
80
|
+
return LoadLayer.loadByFilter(params.loadManager, params.persistence, params.entityConfig, entityScope(params), params.indexerState, params.isPreload, params.item, params.config.ecosystem, filter);
|
|
87
81
|
}
|
|
88
82
|
|
|
89
83
|
function noopSet(_entity) {
|
package/src/Utils.res
CHANGED
|
@@ -273,7 +273,7 @@ module Dict = {
|
|
|
273
273
|
}
|
|
274
274
|
|
|
275
275
|
module Math = {
|
|
276
|
-
let minOptInt = (a
|
|
276
|
+
let minOptInt = (a: option<int>, b: option<int>) =>
|
|
277
277
|
switch (a, b) {
|
|
278
278
|
| (Some(a), Some(b)) => Some(a < b ? a : b)
|
|
279
279
|
| (Some(a), None) => Some(a)
|
|
@@ -374,9 +374,6 @@ module Array = {
|
|
|
374
374
|
/**
|
|
375
375
|
Helper to check if a value exists in an array
|
|
376
376
|
*/
|
|
377
|
-
let includes = (arr: array<'a>, val: 'a) =>
|
|
378
|
-
arr->Array.find(item => item == val)->Stdlib.Option.isSome
|
|
379
|
-
|
|
380
377
|
let isEmpty = (arr: array<_>) =>
|
|
381
378
|
switch arr {
|
|
382
379
|
| [] => true
|
package/src/Utils.res.mjs
CHANGED
|
@@ -6,11 +6,9 @@ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
|
6
6
|
import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
7
7
|
import * as Primitive_int from "@rescript/runtime/lib/es6/Primitive_int.js";
|
|
8
8
|
import * as Stdlib_BigInt from "@rescript/runtime/lib/es6/Stdlib_BigInt.js";
|
|
9
|
-
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
10
9
|
import * as Stdlib_String from "@rescript/runtime/lib/es6/Stdlib_String.js";
|
|
11
10
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
12
11
|
import * as Stdlib_Promise from "@rescript/runtime/lib/es6/Stdlib_Promise.js";
|
|
13
|
-
import * as Primitive_object from "@rescript/runtime/lib/es6/Primitive_object.js";
|
|
14
12
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
15
13
|
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
16
14
|
import * as S$RescriptSchema from "rescript-schema/src/S.res.mjs";
|
|
@@ -221,19 +219,17 @@ let Dict = {
|
|
|
221
219
|
};
|
|
222
220
|
|
|
223
221
|
function minOptInt(a, b) {
|
|
224
|
-
if (a
|
|
222
|
+
if (a !== undefined) {
|
|
225
223
|
if (b !== undefined) {
|
|
226
|
-
return
|
|
224
|
+
return a < b ? a : b;
|
|
227
225
|
} else {
|
|
228
|
-
return;
|
|
226
|
+
return a;
|
|
229
227
|
}
|
|
228
|
+
} else if (b !== undefined) {
|
|
229
|
+
return b;
|
|
230
|
+
} else {
|
|
231
|
+
return;
|
|
230
232
|
}
|
|
231
|
-
let a$1 = Primitive_option.valFromOption(a);
|
|
232
|
-
if (b === undefined) {
|
|
233
|
-
return Primitive_option.some(a$1);
|
|
234
|
-
}
|
|
235
|
-
let b$1 = Primitive_option.valFromOption(b);
|
|
236
|
-
return Primitive_option.some(Primitive_object.lessthan(a$1, b$1) ? a$1 : b$1);
|
|
237
233
|
}
|
|
238
234
|
|
|
239
235
|
let $$Math = {
|
|
@@ -324,10 +320,6 @@ function transposeResults(results) {
|
|
|
324
320
|
};
|
|
325
321
|
}
|
|
326
322
|
|
|
327
|
-
function includes(arr, val) {
|
|
328
|
-
return Stdlib_Option.isSome(arr.find(item => Primitive_object.equal(item, val)));
|
|
329
|
-
}
|
|
330
|
-
|
|
331
323
|
function isEmpty$1(arr) {
|
|
332
324
|
return arr.length === 0;
|
|
333
325
|
}
|
|
@@ -435,7 +427,6 @@ let $$Array$1 = {
|
|
|
435
427
|
clearInPlace: clearInPlace$1,
|
|
436
428
|
setIndexImmutable: setIndexImmutable,
|
|
437
429
|
transposeResults: transposeResults,
|
|
438
|
-
includes: includes,
|
|
439
430
|
isEmpty: isEmpty$1,
|
|
440
431
|
notEmpty: notEmpty,
|
|
441
432
|
awaitEach: awaitEach,
|