|
5 | 5 | DynamicProof,
|
6 | 6 | Proof,
|
7 | 7 | } from "o1js";
|
| 8 | +import _ from "lodash"; |
8 | 9 |
|
9 | 10 | import { TypedClass } from "./types";
|
10 | 11 |
|
@@ -72,6 +73,26 @@ export function reduceSequential<T, U>(
|
72 | 73 | );
|
73 | 74 | }
|
74 | 75 |
|
| 76 | +export function yieldSequential<Source, State, Target>( |
| 77 | + array: Source[], |
| 78 | + callbackfn: ( |
| 79 | + previousValue: State, |
| 80 | + currentValue: Source, |
| 81 | + currentIndex: number, |
| 82 | + array: Source[] |
| 83 | + ) => Promise<[State, Target]>, |
| 84 | + initialValue: State |
| 85 | +): Promise<[State, Target[]]> { |
| 86 | + return reduceSequential<Source, [State, Target[]]>( |
| 87 | + array, |
| 88 | + async ([state, collectedTargets], curr, index, arr) => { |
| 89 | + const [newState, addition] = await callbackfn(state, curr, index, arr); |
| 90 | + return [newState, collectedTargets.concat(addition)]; |
| 91 | + }, |
| 92 | + [initialValue, []] |
| 93 | + ); |
| 94 | +} |
| 95 | + |
75 | 96 | export function mapSequential<T, R>(
|
76 | 97 | array: T[],
|
77 | 98 | f: (element: T, index: number, array: T[]) => Promise<R>
|
@@ -198,3 +219,43 @@ export function safeParseJson<T>(json: string) {
|
198 | 219 | // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
199 | 220 | return JSON.parse(json) as T;
|
200 | 221 | }
|
| 222 | + |
| 223 | +export type Nullable<T> = { |
| 224 | + [Key in keyof T]: T[Key] | undefined; |
| 225 | +}; |
| 226 | + |
| 227 | +export function isFull<T>(t: Nullable<T>): t is T { |
| 228 | + return Object.values(t).findIndex((v) => v === undefined) === -1; |
| 229 | +} |
| 230 | + |
| 231 | +// TODO Restructure utils into separate package and multiple files |
| 232 | + |
| 233 | +export function padArray<T>( |
| 234 | + array: T[], |
| 235 | + batchSize: number, |
| 236 | + generator: (index: number) => T |
| 237 | +): T[] { |
| 238 | + const slice = array.slice(); |
| 239 | + const dummies = range(0, batchSize - (array.length % batchSize)).map((i) => |
| 240 | + generator(i + array.length) |
| 241 | + ); |
| 242 | + slice.push(...dummies); |
| 243 | + return slice; |
| 244 | +} |
| 245 | + |
| 246 | +export function batch<T>( |
| 247 | + arr: T[], |
| 248 | + batchSize: number, |
| 249 | + dummy: (index: number) => T |
| 250 | +): T[][] { |
| 251 | + const padded = padArray(arr, batchSize, dummy); |
| 252 | + |
| 253 | + const partitioned = _.groupBy( |
| 254 | + padded.map((v, i) => [v, i] as const), |
| 255 | + ([v, i]) => Math.floor(i / batchSize) |
| 256 | + ); |
| 257 | + |
| 258 | + const numBatches = Math.ceil(arr.length / batchSize); |
| 259 | + |
| 260 | + return range(0, numBatches).map((i) => partitioned[i].map((x) => x[0])); |
| 261 | +} |
0 commit comments