data-structure-typed 2.0.4 → 2.0.5

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.
@@ -32,74 +32,6 @@ export const arrayRemove = function (array, predicate) {
32
32
  }
33
33
  return result;
34
34
  };
35
- export const THUNK_SYMBOL = Symbol('thunk');
36
- /**
37
- * The function `isThunk` checks if a given value is a function with a specific symbol property.
38
- * @param {any} fnOrValue - The `fnOrValue` parameter in the `isThunk` function can be either a
39
- * function or a value that you want to check if it is a thunk. Thunks are functions that are wrapped
40
- * around a value or computation for lazy evaluation. The function checks if the `fnOrValue` is
41
- * @returns The function `isThunk` is checking if the input `fnOrValue` is a function and if it has a
42
- * property `__THUNK__` equal to `THUNK_SYMBOL`. The return value will be `true` if both conditions are
43
- * met, otherwise it will be `false`.
44
- */
45
- export const isThunk = (fnOrValue) => {
46
- return typeof fnOrValue === 'function' && fnOrValue.__THUNK__ === THUNK_SYMBOL;
47
- };
48
- /**
49
- * The `toThunk` function in TypeScript converts a function into a thunk by wrapping it in a closure.
50
- * @param {ToThunkFn} fn - `fn` is a function that will be converted into a thunk.
51
- * @returns A thunk function is being returned. Thunk functions are functions that delay the evaluation
52
- * of an expression or operation until it is explicitly called or invoked. In this case, the `toThunk`
53
- * function takes a function `fn` as an argument and returns a thunk function that, when called, will
54
- * execute the `fn` function provided as an argument.
55
- */
56
- export const toThunk = (fn) => {
57
- const thunk = () => fn();
58
- thunk.__THUNK__ = THUNK_SYMBOL;
59
- return thunk;
60
- };
61
- /**
62
- * The `trampoline` function in TypeScript enables tail call optimization by using thunks to avoid
63
- * stack overflow.
64
- * @param {TrlFn} fn - The `fn` parameter in the `trampoline` function is a function that takes any
65
- * number of arguments and returns a value.
66
- * @returns The `trampoline` function returns an object with two properties:
67
- * 1. A function that executes the provided function `fn` and continues to execute any thunks returned
68
- * by `fn` until a non-thunk value is returned.
69
- * 2. A `cont` property that is a function which creates a thunk for the provided function `fn`.
70
- */
71
- export const trampoline = (fn) => {
72
- const cont = (...args) => toThunk(() => fn(...args));
73
- return Object.assign((...args) => {
74
- let result = fn(...args);
75
- while (isThunk(result) && typeof result === 'function') {
76
- result = result();
77
- }
78
- return result;
79
- }, { cont });
80
- };
81
- /**
82
- * The `trampolineAsync` function in TypeScript allows for asynchronous trampolining of a given
83
- * function.
84
- * @param {TrlAsyncFn} fn - The `fn` parameter in the `trampolineAsync` function is expected to be a
85
- * function that returns a Promise. This function will be called recursively until a non-thunk value is
86
- * returned.
87
- * @returns The `trampolineAsync` function returns an object with two properties:
88
- * 1. An async function that executes the provided `TrlAsyncFn` function and continues to execute any
89
- * thunks returned by the function until a non-thunk value is returned.
90
- * 2. A `cont` property that is a function which wraps the provided `TrlAsyncFn` function in a thunk
91
- * and returns it.
92
- */
93
- export const trampolineAsync = (fn) => {
94
- const cont = (...args) => toThunk(() => fn(...args));
95
- return Object.assign(async (...args) => {
96
- let result = await fn(...args);
97
- while (isThunk(result) && typeof result === 'function') {
98
- result = await result();
99
- }
100
- return result;
101
- }, { cont });
102
- };
103
35
  /**
104
36
  * The function `getMSB` returns the most significant bit of a given number.
105
37
  * @param {number} value - The `value` parameter is a number for which we want to find the position of
@@ -251,4 +183,142 @@ export function isComparable(value, isForceObjectComparable = false) {
251
183
  return false;
252
184
  return isPrimitiveComparable(comparableValue);
253
185
  }
186
+ /**
187
+ * Creates a trampoline thunk object.
188
+ *
189
+ * A "thunk" is a deferred computation — instead of performing a recursive call immediately,
190
+ * it wraps the next step of the computation in a function. This allows recursive processes
191
+ * to be executed iteratively, preventing stack overflows.
192
+ *
193
+ * @template T - The type of the final computation result.
194
+ * @param computation - A function that, when executed, returns the next trampoline step.
195
+ * @returns A TrampolineThunk object containing the deferred computation.
196
+ */
197
+ export const makeTrampolineThunk = (computation) => ({
198
+ isThunk: true, // Marker indicating this is a thunk
199
+ fn: computation // The deferred computation function
200
+ });
201
+ /**
202
+ * Type guard to check whether a given value is a TrampolineThunk.
203
+ *
204
+ * This function is used to distinguish between a final computation result (value)
205
+ * and a deferred computation (thunk).
206
+ *
207
+ * @template T - The type of the value being checked.
208
+ * @param value - The value to test.
209
+ * @returns True if the value is a valid TrampolineThunk, false otherwise.
210
+ */
211
+ export const isTrampolineThunk = (value) => typeof value === 'object' && // Must be an object
212
+ value !== null && // Must not be null
213
+ 'isThunk' in value && // Must have the 'isThunk' property
214
+ value.isThunk; // The flag must be true
215
+ /**
216
+ * Executes a trampoline computation until a final (non-thunk) result is obtained.
217
+ *
218
+ * The trampoline function repeatedly invokes the deferred computations (thunks)
219
+ * in an iterative loop. This avoids deep recursive calls and prevents stack overflow,
220
+ * which is particularly useful for implementing recursion in a stack-safe manner.
221
+ *
222
+ * @template T - The type of the final result.
223
+ * @param initial - The initial Trampoline value or thunk to start execution from.
224
+ * @returns The final result of the computation (a non-thunk value).
225
+ */
226
+ export function trampoline(initial) {
227
+ let current = initial; // Start with the initial trampoline value
228
+ while (isTrampolineThunk(current)) { // Keep unwrapping while we have thunks
229
+ current = current.fn(); // Execute the deferred function to get the next step
230
+ }
231
+ return current; // Once no thunks remain, return the final result
232
+ }
233
+ /**
234
+ * Wraps a recursive function inside a trampoline executor.
235
+ *
236
+ * This function transforms a potentially recursive function (that returns a Trampoline<Result>)
237
+ * into a *stack-safe* function that executes iteratively using the `trampoline` runner.
238
+ *
239
+ * In other words, it allows you to write functions that look recursive,
240
+ * but actually run in constant stack space.
241
+ *
242
+ * @template Args - The tuple type representing the argument list of the original function.
243
+ * @template Result - The final return type after all trampoline steps are resolved.
244
+ *
245
+ * @param fn - A function that performs a single step of computation
246
+ * and returns a Trampoline (either a final value or a deferred thunk).
247
+ *
248
+ * @returns A new function with the same arguments, but which automatically
249
+ * runs the trampoline process and returns the *final result* instead
250
+ * of a Trampoline.
251
+ *
252
+ * @example
253
+ * // Example: Computing factorial in a stack-safe way
254
+ * const factorial = makeTrampoline(function fact(n: number, acc: number = 1): Trampoline<number> {
255
+ * return n === 0
256
+ * ? acc
257
+ * : makeTrampolineThunk(() => fact(n - 1, acc * n));
258
+ * });
259
+ *
260
+ * console.log(factorial(100000)); // Works without stack overflow
261
+ */
262
+ export function makeTrampoline(fn // A function that returns a trampoline step
263
+ ) {
264
+ // Return a wrapped function that automatically runs the trampoline execution loop
265
+ return (...args) => trampoline(fn(...args));
266
+ }
267
+ /**
268
+ * Executes an asynchronous trampoline computation until a final (non-thunk) result is obtained.
269
+ *
270
+ * This function repeatedly invokes asynchronous deferred computations (thunks)
271
+ * in an iterative loop. Each thunk may return either a Trampoline<T> or a Promise<Trampoline<T>>.
272
+ *
273
+ * It ensures that asynchronous recursive functions can run without growing the call stack,
274
+ * making it suitable for stack-safe async recursion.
275
+ *
276
+ * @template T - The type of the final result.
277
+ * @param initial - The initial Trampoline or Promise of Trampoline to start execution from.
278
+ * @returns A Promise that resolves to the final result (a non-thunk value).
279
+ */
280
+ export async function asyncTrampoline(initial) {
281
+ let current = await initial; // Wait for the initial step to resolve if it's a Promise
282
+ // Keep executing thunks until we reach a non-thunk (final) value
283
+ while (isTrampolineThunk(current)) {
284
+ current = await current.fn(); // Execute the thunk function (may be async)
285
+ }
286
+ // Once the final value is reached, return it
287
+ return current;
288
+ }
289
+ /**
290
+ * Wraps an asynchronous recursive function inside an async trampoline executor.
291
+ *
292
+ * This helper transforms a recursive async function that returns a Trampoline<Result>
293
+ * (or Promise<Trampoline<Result>>) into a *stack-safe* async function that executes
294
+ * iteratively via the `asyncTrampoline` runner.
295
+ *
296
+ * @template Args - The tuple type representing the argument list of the original function.
297
+ * @template Result - The final return type after all async trampoline steps are resolved.
298
+ *
299
+ * @param fn - An async or sync function that performs a single step of computation
300
+ * and returns a Trampoline (either a final value or a deferred thunk).
301
+ *
302
+ * @returns An async function with the same arguments, but which automatically
303
+ * runs the trampoline process and resolves to the *final result*.
304
+ *
305
+ * @example
306
+ * // Example: Async factorial using trampoline
307
+ * const asyncFactorial = makeAsyncTrampoline(async function fact(
308
+ * n: number,
309
+ * acc: number = 1
310
+ * ): Promise<Trampoline<number>> {
311
+ * return n === 0
312
+ * ? acc
313
+ * : makeTrampolineThunk(() => fact(n - 1, acc * n));
314
+ * });
315
+ *
316
+ * asyncFactorial(100000).then(console.log); // Works without stack overflow
317
+ */
318
+ export function makeAsyncTrampoline(fn) {
319
+ // Return a wrapped async function that runs through the async trampoline loop
320
+ return async (...args) => {
321
+ return asyncTrampoline(fn(...args));
322
+ };
323
+ }
254
324
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils/utils.ts"],"names":[],"mappings":"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"}
@@ -146,7 +146,6 @@ var dataStructureTyped = (() => {
146
146
  SkipList: () => SkipList,
147
147
  SkipListNode: () => SkipListNode,
148
148
  Stack: () => Stack,
149
- THUNK_SYMBOL: () => THUNK_SYMBOL,
150
149
  TreeCounter: () => TreeCounter,
151
150
  TreeCounterNode: () => TreeCounterNode,
152
151
  TreeMultiMap: () => TreeMultiMap,
@@ -158,18 +157,20 @@ var dataStructureTyped = (() => {
158
157
  UndirectedGraph: () => UndirectedGraph,
159
158
  UndirectedVertex: () => UndirectedVertex,
160
159
  arrayRemove: () => arrayRemove,
160
+ asyncTrampoline: () => asyncTrampoline,
161
161
  calcMinUnitsRequired: () => calcMinUnitsRequired,
162
162
  getMSB: () => getMSB,
163
163
  isComparable: () => isComparable,
164
- isThunk: () => isThunk,
164
+ isTrampolineThunk: () => isTrampolineThunk,
165
165
  isWeakKey: () => isWeakKey,
166
+ makeAsyncTrampoline: () => makeAsyncTrampoline,
167
+ makeTrampoline: () => makeTrampoline,
168
+ makeTrampolineThunk: () => makeTrampolineThunk,
166
169
  rangeCheck: () => rangeCheck,
167
170
  roundFixed: () => roundFixed,
168
171
  throwRangeError: () => throwRangeError,
169
172
  toBinaryString: () => toBinaryString,
170
- toThunk: () => toThunk,
171
173
  trampoline: () => trampoline,
172
- trampolineAsync: () => trampolineAsync,
173
174
  uuidV4: () => uuidV4
174
175
  });
175
176
 
@@ -623,41 +624,6 @@ var dataStructureTyped = (() => {
623
624
  }
624
625
  return result;
625
626
  };
626
- var THUNK_SYMBOL = Symbol("thunk");
627
- var isThunk = (fnOrValue) => {
628
- return typeof fnOrValue === "function" && fnOrValue.__THUNK__ === THUNK_SYMBOL;
629
- };
630
- var toThunk = (fn) => {
631
- const thunk = () => fn();
632
- thunk.__THUNK__ = THUNK_SYMBOL;
633
- return thunk;
634
- };
635
- var trampoline = (fn) => {
636
- const cont = (...args) => toThunk(() => fn(...args));
637
- return Object.assign(
638
- (...args) => {
639
- let result = fn(...args);
640
- while (isThunk(result) && typeof result === "function") {
641
- result = result();
642
- }
643
- return result;
644
- },
645
- { cont }
646
- );
647
- };
648
- var trampolineAsync = (fn) => {
649
- const cont = (...args) => toThunk(() => fn(...args));
650
- return Object.assign(
651
- (...args) => __async(void 0, null, function* () {
652
- let result = yield fn(...args);
653
- while (isThunk(result) && typeof result === "function") {
654
- result = yield result();
655
- }
656
- return result;
657
- }),
658
- { cont }
659
- );
660
- };
661
627
  var getMSB = (value) => {
662
628
  if (value <= 0) {
663
629
  return 0;
@@ -708,6 +674,40 @@ var dataStructureTyped = (() => {
708
674
  if (comparableValue === null || comparableValue === void 0) return false;
709
675
  return isPrimitiveComparable(comparableValue);
710
676
  }
677
+ var makeTrampolineThunk = (computation) => ({
678
+ isThunk: true,
679
+ // Marker indicating this is a thunk
680
+ fn: computation
681
+ // The deferred computation function
682
+ });
683
+ var isTrampolineThunk = (value) => typeof value === "object" && // Must be an object
684
+ value !== null && // Must not be null
685
+ "isThunk" in value && // Must have the 'isThunk' property
686
+ value.isThunk;
687
+ function trampoline(initial) {
688
+ let current = initial;
689
+ while (isTrampolineThunk(current)) {
690
+ current = current.fn();
691
+ }
692
+ return current;
693
+ }
694
+ function makeTrampoline(fn) {
695
+ return (...args) => trampoline(fn(...args));
696
+ }
697
+ function asyncTrampoline(initial) {
698
+ return __async(this, null, function* () {
699
+ let current = yield initial;
700
+ while (isTrampolineThunk(current)) {
701
+ current = yield current.fn();
702
+ }
703
+ return current;
704
+ });
705
+ }
706
+ function makeAsyncTrampoline(fn) {
707
+ return (...args) => __async(this, null, function* () {
708
+ return asyncTrampoline(fn(...args));
709
+ });
710
+ }
711
711
 
712
712
  // src/utils/number.ts
713
713
  function toBinaryString(num, digit = 32) {
@@ -8909,14 +8909,16 @@ var dataStructureTyped = (() => {
8909
8909
  if (!this.isRealNode(startNode)) return callback(startNode);
8910
8910
  if (iterationType === "RECURSIVE") {
8911
8911
  const dfs = (cur) => {
8912
- if (!this.isRealNode(cur.left)) return cur;
8913
- return dfs(cur.left);
8912
+ const { left } = cur;
8913
+ if (!this.isRealNode(left)) return cur;
8914
+ return dfs(left);
8914
8915
  };
8915
8916
  return callback(dfs(startNode));
8916
8917
  } else {
8917
- const dfs = trampoline((cur) => {
8918
- if (!this.isRealNode(cur.left)) return cur;
8919
- return dfs.cont(cur.left);
8918
+ const dfs = makeTrampoline((cur) => {
8919
+ const { left } = cur;
8920
+ if (!this.isRealNode(left)) return cur;
8921
+ return makeTrampolineThunk(() => dfs(left));
8920
8922
  });
8921
8923
  return callback(dfs(startNode));
8922
8924
  }
@@ -8949,14 +8951,16 @@ var dataStructureTyped = (() => {
8949
8951
  if (!startNode) return callback(startNode);
8950
8952
  if (iterationType === "RECURSIVE") {
8951
8953
  const dfs = (cur) => {
8952
- if (!this.isRealNode(cur.right)) return cur;
8953
- return dfs(cur.right);
8954
+ const { right } = cur;
8955
+ if (!this.isRealNode(right)) return cur;
8956
+ return dfs(right);
8954
8957
  };
8955
8958
  return callback(dfs(startNode));
8956
8959
  } else {
8957
- const dfs = trampoline((cur) => {
8958
- if (!this.isRealNode(cur.right)) return cur;
8959
- return dfs.cont(cur.right);
8960
+ const dfs = makeTrampoline((cur) => {
8961
+ const { right } = cur;
8962
+ if (!this.isRealNode(right)) return cur;
8963
+ return makeTrampolineThunk(() => dfs(right));
8960
8964
  });
8961
8965
  return callback(dfs(startNode));
8962
8966
  }