UNPKG

33.1 kBTypeScriptView Raw
1export interface FunctionLibrary {
2 [name: string]: (...args: any[]) => any
3}
4interface Looper<T> {}
5
6type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
7
8interface AbstractGraph {
9 $isCarmiGraph: true
10}
11export interface GraphBase<NativeType> extends AbstractGraph {
12 $value: NativeType
13}
14
15export type AsNative<T> = T extends GraphBase<infer N> ? N : T
16export type Argument<T> = AsNative<T> | GraphBase<T> | T
17
18type AsNativeRecursive<T> = AsNative<T> extends any[]
19 ? AsNative<T>
20 : AsNative<T> extends object
21 ? { [k in keyof AsNative<T>]: AsNative<AsNative<T>[k]> }
22 : AsNative<T>
23type BoundFunction<F, A = unknown, B = unknown, C = unknown, D = unknown, E = unknown> = unknown extends A
24 ? (F extends (...args: infer Args) => infer R ? F : never)
25 : unknown extends B
26 ? (F extends (a: A, ...args: infer Args) => infer R ? (...args: Args) => R : never)
27 : unknown extends C
28 ? (F extends (a: A, b: B, ...args: infer Args) => infer R ? (...args: Args) => R : never)
29 : unknown extends D
30 ? (F extends (a: A, b: B, c: C, ...args: infer Args) => infer R ? (...args: Args) => R : never)
31 : unknown extends E
32 ? (F extends (a: A, b: B, c: C, d: D, ...args: infer Args) => infer R ? (...args: Args) => R : never)
33 : never
34
35export interface BoolGraph<F extends FunctionLibrary> extends GraphImpl<boolean, F> {}
36export interface FunctionGraph<N, F extends FunctionLibrary> extends GraphImpl<N, F> {}
37
38/**
39 * Graph
40 */
41interface GraphImpl<NativeType, F extends FunctionLibrary> extends GraphBase<NativeType> {
42 /**
43 * Returns a graph that resolves to the return type of a named function from the function library.
44 *
45 * @param func A function name from the function library
46 * @param args Args to pass, in addition to the value resolved from ""
47 */
48 call<
49 FunctionName extends keyof F,
50 Arguments extends F[FunctionName] extends (firstArg: NativeType, ...args: infer Args) => any ? Args : never
51 >(
52 func: FunctionName,
53 ...args: Arguments extends (infer A)[] ? Argument<A>[] : never
54 ): Graph<ReturnType<F[FunctionName]>, F>
55 /**
56 * Like call but will exectue even if the parameters mutation resulted in the same values.
57 * **Please note**: `effect(func, args)` is a leaf and ends the chain, and its return value cannot be used.
58 */
59 effect<
60 FunctionName extends keyof F,
61 Arguments extends F[FunctionName] extends (firstArg: NativeType, ...args: infer Args) => any ? Args : never
62 >(
63 func: FunctionName,
64 ...args: Arguments extends (infer A)[] ? Argument<A>[] : never
65 ): void
66
67 /**
68 * Creates a function that invokes functionName from the function library with args prepended to the arguments it receives.
69 */
70 bind<FunctionName extends keyof F>(func: FunctionName): FunctionGraph<BoundFunction<F[FunctionName], NativeType>, F>
71 bind<FunctionName extends keyof F, A>(
72 func: FunctionName,
73 a: A
74 ): FunctionGraph<BoundFunction<F[FunctionName], NativeType, A>, F>
75 bind<FunctionName extends keyof F, A, B>(
76 func: FunctionName,
77 a: A,
78 b: B
79 ): FunctionGraph<BoundFunction<F[FunctionName], NativeType, A, B>, F>
80 bind<FunctionName extends keyof F, A, B, C>(
81 func: FunctionName,
82 a: A,
83 b: B,
84 c: C
85 ): FunctionGraph<BoundFunction<F[FunctionName], NativeType, A, B, C>, F>
86 bind<FunctionName extends keyof F, A, B, C, D>(
87 func: FunctionName,
88 a: A,
89 b: B,
90 c: C,
91 d: D
92 ): FunctionGraph<BoundFunction<F[FunctionName], NativeType, A, B, C, D>, F>
93
94 /**
95 * Generates a breakpoint (debugger clause), continuing the graph.
96 */
97 breakpoint(): this
98
99 /**
100 * Generates a console statement, continuing the chain.
101 * @param label if provided, label is printed alongside the trace info
102 */
103 trace(label?: string): this
104
105 /**
106 * Generates a console statement, continuing the chain if condition resolves to true.
107 * @param condition
108 * @sugar */
109 conditionalTrace<FunctionName extends keyof F>(condition: FunctionName): this
110
111 /**
112 * Triggers a breakpoint if the condition resolves to true.
113 * @param condition
114 * @sugar */
115 conditionalBreakpoint<FunctionName extends keyof F>(condition: FunctionName): this
116
117 /**
118 * Lets you tap into the value and traces the result of tapFn.
119 * @param tapFn
120 * @sugar */
121 tapTrace<FunctionName extends keyof F>(tapFn: FunctionName): this
122
123 /**
124 * Resolves to `!NativeType`.
125 */
126 not(): BoolGraph<F>
127
128 /**
129 * Resolves to either consequence or alternate, based on the value of NativeType.
130 * Note that both options will be evaluated, even if one of them is not semantically possible.
131 *
132 * @param consequence graph if NativeType value is truthy
133 * @param alternate graph is NativeType value is falsey
134 */
135 ternary<Consequence, Alternate>(
136 consequence: Consequence,
137 alternate: Alternate
138 ): Graph<
139 AsNative<Consequence> extends AsNative<Alternate>
140 ? Consequence
141 : AsNative<Alternate> extends AsNative<Consequence>
142 ? Alternate
143 : Consequence extends null
144 ? Alternate
145 : Alternate extends null
146 ? Consequence
147 : Alternate | Consequence,
148 F
149 >
150
151 /**
152 * Resolves to the case that matches equals to the boxed value.
153 *
154 * @param caseTuples An array of pairs between a value and a consequent
155 * @param defaultCase The graph to return in case no given case matches the boxed value
156 * @sugar */
157 switch<DefaultCase, TupleType extends [Argument<NativeType>, any]>(
158 caseTuples: Array<TupleType>,
159 defaultCase: DefaultCase
160 ): Graph<DefaultCase, F> | Graph<TupleType extends [Argument<NativeType>, infer Result] ? Result : never, F>
161
162 /**
163 * Returns a boolean graph that resolves to the value of (NativeType === other).
164 * @param other
165 */
166 eq(other: Argument<unknown>): BoolGraph<F>
167
168 /**
169 * When run on a key inside a recursiveMap/recursiveMapValues functor,
170 * will return the resolved value for a given key. NativeType allows returning values for indicies of a map based on other values.
171 * @param loop passed to the functor of recursiveMap/recursiveMapValues
172 */
173 recur<ValueType>(loop: Looper<ValueType>): ValueType
174
175 /**
176 * Returns true if the context is of type `Array`.
177 */
178 isArray(): BoolGraph<F>
179
180 /**
181 * Returns true if the context is `undefined`.
182 */
183 isUndefined(): BoolGraph<F>
184
185 /**
186 * Returns true if the context is of type `boolean`.
187 */
188 isBoolean(): BoolGraph<F>
189
190 /**
191 * Returns true if the context is of type `number`.
192 */
193 isNumber(): BoolGraph<F>
194
195 /**
196 * Returns true if the context is of type `string`.
197 */
198 isString(): BoolGraph<F>
199}
200
201/**
202 * Number
203 */
204export interface NumberGraph<NativeType extends number, F extends FunctionLibrary> extends GraphImpl<NativeType, F> {
205 /**
206 * Resolves to (NativeType > other).
207 * @param other
208 */
209 gt(other: Argument<number>): BoolGraph<F>
210
211 /**
212 * Resolves to (NativeType >= other).
213 * @param other
214 */
215 gte(other: Argument<number>): BoolGraph<F>
216
217 /**
218 * Resolves to (NativeType < other).
219 * @param other
220 */
221 lt(other: Argument<number>): BoolGraph<F>
222
223 /**
224 * Resolves to (NativeType <= other).
225 * @param other
226 */
227 lte(other: Argument<number>): BoolGraph<F>
228
229 /**
230 * Resolves to (NativeType - other).
231 * @param other
232 */
233 minus(value: Argument<number>): NumberGraph<number, F>
234
235 /**
236 * Resolves to (NativeType * other).
237 * @param other
238 * @example
239 * const { root } = require('carmi')
240 * const instance = createInstance({
241 * output: root.mult(2)
242 * }, 2)
243 * instance.output //4
244 */
245 mult(value: Argument<number>): NumberGraph<number, F>
246
247 /**
248 * Resolves to (NativeType + other).
249 * @param other
250 */
251 plus(num: Argument<number>): NumberGraph<number, F>
252 plus(str: Argument<string>): StringGraph<string, F>
253
254 /**
255 * Resolves to (NativeType / other).
256 * @param other
257 */
258 div(value: Argument<number>): NumberGraph<number, F>
259
260 /**
261 * Resolves to (NativeType % other).
262 * @param other
263 */
264 mod(value: Argument<number>): NumberGraph<number, F>
265
266 /**
267 * Creates a number array graph.
268 *
269 * @param start number to start from
270 * @param skip number to skip between values
271 * @returns a number array graph, with size equal to resolved "NativeType"
272 */
273 range(start?: Argument<number>, skip?: Argument<number>): NumberGraph<number, F>[]
274
275 /**
276 * Resolves to Math.floor(NativeType).
277 */
278 floor(): NumberGraph<number, F>
279
280 /**
281 * Resolves to Math.ceil(NativeType).
282 */
283 ceil(): NumberGraph<number, F>
284
285 /**
286 * Resolves to Math.round(NativeType).
287 */
288 round(): NumberGraph<number, F>
289}
290
291/**
292 * String
293 */
294export interface StringGraph<NativeType extends string, F extends FunctionLibrary> extends GraphImpl<NativeType, F> {
295 /**
296 * Resolves to (NativeType.startsWith(s)).
297 * @param s other string
298 */
299 startsWith(s: Argument<string>): BoolGraph<F>
300
301 /**
302 * Resolves to (NativeType.endsWith(s)).
303 * @param s other string
304 */
305 endsWith(s: Argument<string>): BoolGraph<F>
306
307 /**
308 * Resolves to (NativeType + s).
309 * @param other other string
310 */
311 plus(other: Argument<string | number>): StringGraph<string, F>
312
313 /**
314 * Resolves to an array graph, like NativeType.split(separator).
315 * @param separator
316 */
317 split(separator: Argument<string>): ArrayGraph<string[], F>
318
319 /**
320 * Resolves to NativeType.toUpperCase().
321 */
322 toUpperCase(): StringGraph<string, F>
323
324 /**
325 * Resolves to NativeType.toLowerCase().
326 */
327 toLowerCase(): StringGraph<string, F>
328
329 /**
330 * Returns the string length.
331 */
332 stringLength(): NumberGraph<number, F>
333
334 /**
335 * Resolves `String.substring`.
336 * @param start
337 * @param end
338 *
339 * Resolves String.substring
340 */
341 substring(start: Argument<number>, end: Argument<number>): StringGraph<string, F>
342
343 /**
344 * Resolves to parseInt(NativeType, radix).
345 * @param radix base (10, 16 etc)
346 */
347 parseInt(radix?: number): NumberGraph<number, F>
348
349 /**
350 * Resolves to parseFloat(NativeType).
351 */
352 parseFloat(): NumberGraph<number, F>
353}
354
355/**
356 * Array or Object
357 */
358interface ArrayOrObjectGraphImpl<NativeType extends any[] | object, F extends FunctionLibrary, Key = keyof NativeType>
359 extends GraphImpl<NativeType, F> {
360 /**
361 * Returns the specific key/index from the object/array.
362 */
363 get<K extends keyof NativeType>(
364 key: K | AbstractGraph
365 ): K extends AbstractGraph ? Graph<NativeType[keyof NativeType], F> : Graph<NativeType[K], F>
366
367 /**
368 * Checks if the object or array graph is empty.
369 @sugar */
370 isEmpty(): BoolGraph<F>
371
372 /**
373 * Resolves to the deep value provided by the path.
374 * @param path
375 * @sugar */
376 getIn<K extends keyof NativeType>(path: [Argument<K>]): Graph<NativeType[K], F>
377 getIn<
378 K0 extends keyof NativeType,
379 K1 extends keyof V0,
380 V0 = NonNullable<NativeType[K0]>
381 >(
382 path: [Argument<K0>, Argument<K1>]
383 ): Graph<V0[K1], F>
384 getIn<
385 K0 extends keyof NativeType,
386 K1 extends keyof V0,
387 K2 extends keyof V1,
388 V0 = NonNullable<NativeType[K0]>,
389 V1 = NonNullable<V0[K1]>
390 >(
391 path: [Argument<K0>, Argument<K1>, Argument<K2>]
392 ): Graph<V1[K2], F>
393 getIn<
394 K0 extends keyof NativeType,
395 K1 extends keyof V0,
396 K2 extends keyof V1,
397 K3 extends keyof V2,
398 V0 = NonNullable<NativeType[K0]>,
399 V1 = NonNullable<V0[K1]>,
400 V2 = NonNullable<V1[K2]>
401 >(
402 path: [Argument<K0>, Argument<K1>, Argument<K2>, Argument<K3>]
403 ): Graph<V2[K3], F>
404 getIn<
405 K0 extends keyof NativeType,
406 K1 extends keyof V0,
407 K2 extends keyof V1,
408 K3 extends keyof V2,
409 K4 extends keyof V3,
410 V0 = NonNullable<NativeType[K0]>,
411 V1 = NonNullable<V0[K1]>,
412 V2 = NonNullable<V1[K2]>,
413 V3 = NonNullable<V2[K3]>
414 >(
415 path: [Argument<K0>, Argument<K1>, Argument<K2>, Argument<K3>, Argument<K4>]
416 ): Graph<V3[K4], F>
417 getIn<
418 K0 extends keyof NativeType,
419 K1 extends keyof V0,
420 K2 extends keyof V1,
421 K3 extends keyof V2,
422 K4 extends keyof V3,
423 K5 extends keyof V4,
424 V0 = NonNullable<NativeType[K0]>,
425 V1 = NonNullable<V0[K1]>,
426 V2 = NonNullable<V1[K2]>,
427 V3 = NonNullable<V2[K3]>,
428 V4 = NonNullable<V3[K4]>
429 >(
430 path: [Argument<K0>, Argument<K1>, Argument<K2>, Argument<K3>, Argument<K4>, Argument<K5>]
431 ): Graph<V4[K5], F>
432 getIn<
433 K0 extends keyof NativeType,
434 K1 extends keyof V0,
435 K2 extends keyof V1,
436 K3 extends keyof V2,
437 K4 extends keyof V3,
438 K5 extends keyof V4,
439 K6 extends keyof V5,
440 V0 = NonNullable<NativeType[K0]>,
441 V1 = NonNullable<V0[K1]>,
442 V2 = NonNullable<V1[K2]>,
443 V3 = NonNullable<V2[K3]>,
444 V4 = NonNullable<V3[K4]>,
445 V5 = NonNullable<V4[K5]>
446 >(
447 path: [Argument<K0>, Argument<K1>, Argument<K2>, Argument<K3>, Argument<K4>, Argument<K5>, Argument<K6>]
448 ): Graph<V5[K6], F>
449 /**
450 * Returns true if the key/index exists on the object/array.
451 */
452 has(key: Argument<string> | Argument<number>): BoolGraph<F>
453}
454
455/**
456 * Array
457 */
458interface ArrayGraphImpl<
459 NativeType extends any[],
460 F extends FunctionLibrary,
461 Value = NativeType extends (infer V)[] ? AsNative<V> : never,
462 Key = keyof NativeType,
463 ValueGraph = Graph<Value, F>,
464 KeyGraph = NumberGraph<number, F>
465> extends ArrayOrObjectGraphImpl<Value[], F> {
466 /**
467 * Resolves to NativeType.length
468 */
469 size(): NumberGraph<NativeType['length'], F>
470
471 /**
472 * Combines all array values of the object. Like: `_.reduce(NativeType, _.assign, {})`
473 */
474 assign<T = NativeType extends object ? true : never>(): ObjectGraph<
475 // @ts-ignore
476 AsNativeRecursive<UnionToIntersection<Value>>,
477 F
478 >
479
480 /**
481 * Combines all array values of the object, in reverse order. Like: `_.reduce(NativeType, _.defaults, {})`
482 */
483 defaults<T = NativeType extends object ? true : never>(): ObjectGraph<
484 // @ts-ignore
485 AsNativeRecursive<UnionToIntersection<Value>>,
486 F
487 >
488
489 /**
490 * Resolves to the first item in an array.
491 * @sugar */
492 head(): ValueGraph
493
494 /**
495 * Resolves to the last item in an array.
496 * @sugar */
497 last(): ValueGraph
498
499 /**
500 * Resolves to the sum of numbers in a number array.
501 *
502 */
503 sum(): Value extends number ? NumberGraph<number, F> : never
504
505 /**
506 * Reverses the order of a given array.
507 * @sugar */
508 reverse(): ArrayGraph<Value[], F>
509
510 /**
511 * Runs the functor for every item in an array. Returns a graph that resolves to an array with the returned values.
512 *
513 * @param functor A function to run for every item of the array
514 * @param scope A variable to pass to the functor if inside another functor.
515 * @example
516 * const { root } = require('carmi')
517 * const instance = createInstance({
518 * output: root.map( item => item.mult(2))
519 * }, [3, 2, 1])
520 * instance.output //[6, 4, 2]
521 */
522 map<Scope, T extends (value: ValueGraph, key: KeyGraph, scope: Scope) => any>(
523 functor: T,
524 scope?: Scope
525 ): ArrayGraph<Array<AsNativeRecursive<ReturnType<T>>>, F>
526
527 /**
528 * Returns a graph that resolves to an array with the value at propName of each corresponding entry.
529 *
530 * @param propName The property name
531 * @example
532 * const { root } = require('carmi')
533 * const input = [{age: 3}, {age: 2}, {age: 1}]
534 * const instance = createInstance({
535 * output: root.map('age')
536 * }, input)
537 * instance.output //[3, 2, 1]
538 */
539 map<K extends keyof Value>(propName: K): ArrayGraph<Array<Value[K]>, F>
540
541 /**
542 * Returns a boolean graph that resolves to *true* if at least one element in the array
543 * passes the test implemented by the provided functor.
544 *
545 * @param functor A function to run for every item of the array, returning boolean
546 * @param scope A variable to pass to the functor if inside another functor.
547 * @example
548 * const { root } = require('carmi')
549 * const instance = createInstance({
550 * output: root.any((value, index) => value.eq(2))
551 * }, [3, 2, 1])
552 * instance.output //true
553 */
554 any<Scope>(
555 functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<boolean>,
556 scope?: Scope
557 ): BoolGraph<F>
558
559 /**
560 * Returns a boolean graph that resolves to true if running the functor on all of the array's items resolved to true.
561 *
562 * @param functor A function to run for every item of the array, returning boolean
563 * @param scope A variable to pass to the functor if inside another functor.
564 * @sugar */
565 every<Scope>(
566 functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<boolean>,
567 scope?: Scope
568 ): BoolGraph<F>
569
570 /**
571 * Returns an object graph that resolves to an object containing keys returned by functor, pointing to their first found corresponding value.
572 *
573 * @param functor A function to run for every item of the array, returning a string as a new key
574 * @param scope A variable to pass to the functor if inside another functor.
575 * @example
576 * const { root, chain } = require('carmi');
577 * const instance = createInstance({
578 * output: root
579 * .keyBy(item => item.get('items').size())
580 * .mapValues(item => item.get('items'))
581 * }, [{items: [1]}, {items: [1, 2]}, {items: [1, 2, 3]}, {items: [1, 2, 3, 4]}]);
582 * instance.output // {1: [1], 2: [1, 2], 3: [1, 2, 3], 4: [1, 2, 3, 4]}
583 **/
584 keyBy<Scope, Ret extends Argument<string | number>>(
585 functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<Ret>,
586 scope?: Scope
587 ): ObjectGraph<Ret extends string ? { [name in Ret]: Value } : { [name: string]: Value }, F>
588
589 /**
590 * Returns an array graph containing only the values for which the functor resolved to `true`.
591 *
592 * @param functor A function to run for every item of the array, returning a boolean
593 * @param scope A variable to pass to the functor if inside another functor.
594 * @example
595 * const { root } = require('carmi')
596 * const instance = createInstance({
597 * output: root.filter( item => item.mod(2))
598 * }, [3, 2, 1])
599 * instance.output //[3, 1]
600 */
601 filter<Scope>(functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => any, scope?: Scope): ArrayGraph<Value[], F>
602
603 /**
604 * Resolved to the index of the first value for which the functor resolved to true, or -1 if not found.
605 *
606 * @param functor A function to run for every item of the array, returning a boolean
607 * @param scope A variable to pass to the functor if inside another functor.
608 * @sugar */
609 findIndex<Scope>(
610 functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<boolean>,
611 scope?: Scope
612 ): KeyGraph
613
614 /**
615 * Returns a value that is a result of running functor on all the items of the array in order, each time with the previous result of functor.
616 *
617 * @param functor A function to run for every item of the array, with the previous value as aggregate
618 * @param initialValue The aggregate to pass to the first argument.
619 * @sugar */
620 reduce<Ret>(
621 functor: (aggregate: Argument<Ret>, value: ValueGraph, key: KeyGraph) => Argument<Ret>,
622 initialValue?: Ret
623 ): NativeType extends any[] ? Ret : never
624
625 /**
626 * Resolves to an array which is a concatenated results of NativeType and one or more additional arrays.
627 * @param arrays
628 * @sugar */
629 concat<T>(...arrays: Argument<T[]>[]): ArrayGraph<(Value | T)[], F>
630
631 /**
632 * Resolves to an array of unique values that are included in given arrays.
633 * @param arrays
634 * @sugar */
635 intersection<T>(...arrays: Argument<T[]>[]): ArrayGraph<(Value | T)[], F>
636
637 /**
638 * Resolves to the first value for which the functor resolves to `true`.
639 *
640 * @param functor A function to run for every item of the array, returning a boolean
641 * @param scope A variable to pass to the functor if inside another functor.
642 * @sugar */
643 find<Scope>(functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<boolean>, scope?: Scope): ValueGraph
644
645 /**
646 * Joins an array of strings to a single string, like `NativeType.join(separator)`.
647 * @param separator
648 * @sugar */
649 join(separator: Argument<string>): Value extends string ? StringGraph<string, F> : never
650
651 /**
652 * Returns an array graph with an additional element (value) at the end.
653 *
654 * @param value A value to add to the array, or a graph resolving to that value
655 * @sugar */
656 append<T>(value: Argument<T>): ArrayGraph<(Value | T)[], F>
657
658 /**
659 * Flattens inner arrays into an array.
660 */
661 flatten<T = Value extends any[] ? true : never>(): ValueGraph
662
663 /**
664 * Resolves to true if the array contains an argument equal to value.
665 * @param value
666 * @sugar */
667 includes(value: Argument<Value>): BoolGraph<F>
668
669 /**
670 * Resolves to the same array, with only `true` values
671 * @sugar */
672 compact(): this
673
674 /**
675 * Resolves to a duplicate-free version of an array
676 * @sugar */
677 uniq(): this
678
679 /**
680 * Resolves to an array with size identical to NativeType, with each element resolving to the result of functor on the equivalent element in NativeType.
681 * The functor is given a "loop" parameter, which can be used to retrieve the functor's result on a different key. For example:
682 *
683 * // Will resolve to [1, 2, 4, 8, ...]
684 * recursiveMap((loop, value, key) => key.eq(0).ternary(1, key.minus(1).recur(loop).multiply(2)))
685 *
686 * @param functor
687 * @param scope
688 */
689 recursiveMap<Scope, Ret>(
690 functor: (loop: Looper<Ret>, value: Value, key: Key, scope: Scope) => Argument<Ret>,
691 scope?: Scope
692 ): ArrayGraph<Ret[], F>
693}
694
695/**
696 * Object
697 */
698
699interface ObjectGraphImpl<
700 NativeType extends { [key: string]: any },
701 F extends FunctionLibrary,
702 Key = keyof NativeType & string,
703 Value = AsNative<NativeType[keyof NativeType]>,
704 ValueGraph = Graph<Value, F>,
705 KeyGraph = Graph<Key, F>
706> extends ArrayOrObjectGraphImpl<{ [key in keyof NativeType]: AsNative<NativeType[key]> }, F> {
707 /**
708 * Resolves to the number of keys in the object
709 */
710 size(): NumberGraph<number, F>
711
712 /**
713 * Resolves to true if NativeType has the given key as a key
714 * @param key A potential key of NativeType
715 */
716 has(key: Argument<string>): BoolGraph<F>
717
718 /**
719 * Resolves to true if NativeType object has a value equal to the value argument.
720 *
721 * @param value
722 * @sugar */
723 includesValue(value: Argument<Value>): BoolGraph<F>
724
725 /**
726 * Resolves to a new object with the entries for which the functor has resolved to true.
727 *
728 * @param functor
729 * @param scope
730 */
731 filterBy<Scope>(functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => any, scope?: Scope): this
732
733 /**
734 * Resolves to a new object with only the keys passed as argument
735 *
736 * @param keys
737 * @sugar */
738 pick<K extends keyof NativeType, Keys extends Array<K>>(keys: Keys): ObjectGraph<Pick<NativeType, Keys[number]>, F>
739
740 /**
741 * Resolves to an object with the same keys, with each value resolves to the return value of functor on the corresponding entry.
742 *
743 * @param functor
744 * @param scope
745 */
746 mapValues<Scope, T extends (value: ValueGraph, key: KeyGraph, scope: Scope) => any>(
747 functor: T,
748 scope?: Scope
749 ): ObjectGraph<{ [name in keyof NativeType]: AsNativeRecursive<ReturnType<T>> }, F>
750
751 /**
752 * Resolves to an object with the same keys, with each value resolves to the value at propName of the corresponding entry.
753 * This is equivalent to x => x.get(propName)
754 *
755 * @param propName property name
756 */
757 mapValues<K extends keyof Value>(
758 propName: Argument<K>
759 ): ObjectGraph<{ [name in keyof NativeType]: AsNativeRecursive<Value[K]> }, F>
760
761 /**
762 * Resolves to an object with the same values, with each key resolves to the return value of functor on the corresponding entry.
763 *
764 * @param functor
765 * @param scope
766 */
767 mapKeys<Scope, T extends (value: ValueGraph, key: KeyGraph, scope: Scope) => any>(
768 functor: T,
769 scope?: Scope
770 ): ObjectGraph<{ [key in ReturnType<T> extends string ? ReturnType<T> : string]: Value }, F>
771
772 /**
773 * Resolves to an object with the same values, with each key resolves to the value at propName of the corresponding entry.
774 *
775 * @param propName property name
776 */
777 mapKeys<K extends keyof Value>(propName: Argument<K>): ObjectGraph<{ [key: string]: Value }, F>
778
779 /**
780 * Resolves to a boolean representing whether the object contains any value for which the functor has resolved to true
781 *
782 * @param functor
783 * @param scope
784 */
785 anyValues<Scope>(
786 functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<boolean>,
787 scope?: Scope
788 ): BoolGraph<F>
789
790 /**
791 * Returns a new object with the keys returned by the functor, and the values resolves to arrays with all the elements which returned that key.
792 */
793 groupBy<Scope, Ret>(
794 functor: (value: ValueGraph, key: KeyGraph, scope: Scope) => Argument<Ret>,
795 scope?: Scope
796 ): ObjectGraph<{ [key: string]: NativeType }, F>
797
798 /**
799 * Returns a new object which resolves to `_.assign(NativeType, value)`.
800 *
801 * @param value
802 * @sugar */
803 assignIn<V extends object>(value: Argument<V>[]): ObjectGraph<NativeType & AsNativeRecursive<V>, F>
804
805 /**
806 * Sets value for given key.
807 *
808 * @param key The property name
809 * @param value The value to set
810 * @sugar */
811 simpleSet<Key extends string, Value>(key: Key, value: Argument<Value>): ObjectGraph<NativeType & {[key in Key]: Value}, F>
812
813 /**
814 * Sets value for given path.
815 *
816 * @param path[] Array
817 * @param value
818 * @sugar */
819 setIn(path: string[], value: any): ObjectGraph<NativeType, F>
820
821 /**
822 * Resolves to an object with keys identical to NativeType, with each element resolving to the result of functor on the equivalent element in NativeType.
823 * The functor is given a "loop" parameter, which can be used to retrieve the functor's result on a different key. For example:
824 *
825 * @param functor
826 * @param scope
827 */
828 recursiveMapValues<
829 Scope,
830 Functor extends (looper: Looper<unknown>, value: ValueGraph, key: KeyGraph, scope: Scope) => any
831 >(
832 functor: Functor,
833 scope?: Scope
834 ): ObjectGraph<{ [name in keyof NativeType]: AsNativeRecursive<ReturnType<Functor>> }, F>
835
836 /**
837 * Resolves to an array representing the keys of the object.
838 *
839 */
840 keys(): ArrayGraph<Key[], F>
841
842 /**
843 * Resolves to an array representing the values of the object.
844 *
845 */
846 values(): ArrayGraph<Value[], F>
847}
848
849interface Expression {}
850export interface Token {
851 $type: string
852}
853type PathSegment = Token | string | number
854type SetterExpression<Model, Path, F> = {}
855type SpliceExpression<Model, Path, F> = {}
856type PushExpression<Model, Path, F> = {}
857
858export interface ArrayGraph<T extends any[], F extends FunctionLibrary> extends ArrayGraphImpl<T, F> {}
859export interface ObjectGraph<T extends object, F extends FunctionLibrary> extends ObjectGraphImpl<AsNative<T>, F> {}
860
861export type Graph<N, F extends FunctionLibrary> = N extends AbstractGraph
862 ? N
863 : N extends any[]
864 ? ArrayGraph<N, F>
865 : N extends Function
866 ? FunctionGraph<N, F>
867 : N extends string
868 ? StringGraph<N, F>
869 : N extends number
870 ? NumberGraph<N, F>
871 : N extends boolean
872 ? BoolGraph<F>
873 : N extends object
874 ? ObjectGraph<N, F>
875 : never
876
877/**
878 * External
879 */
880export interface CarmiAPI<Schema extends object = any, F extends FunctionLibrary = any> {
881 $schema: Schema
882 $functions: F
883 root: ObjectGraph<Schema, F>
884
885 /**
886 * Wraps a native JS object with the declarative APIs.
887 *
888 * @example
889 * const { root, chain } = require('carmi');
890 * const instance = createInstance({
891 * output: chain([{
892 * shelf: root.get(0).get('shelf'),
893 * books: [ root.get(1).get(root.get(0).get('shelf')).get(0) ]
894 * }])
895 * .assign()
896 * }, [{shelf: 'scifi'}, {scifi: ['a scanner darkly']}]);
897 * instance.output //{books: ["a scanner darkly"], shelf: "scifi"}
898 */
899 chain<T>(t: T): Graph<AsNativeRecursive<T>, F>
900
901 /**
902 * Logical operand or.
903 */
904 or<A>(a: A, b: never[] | {}): Graph<A, F>
905 or<A, B>(a: A, b: B, c: never[] | {}): Graph<A, F> | Graph<B, F>
906 or<A, B, C>(a: A, b: B, c: C, d: never[] | {}): Graph<A, F> | Graph<B, F> | Graph<C, F>
907 or<A, B, C, D>(a: A, b: B, c: C, d: D, e: never[] | {}): Graph<A, F> | Graph<B, F> | Graph<C, F> | Graph<D, F>
908 or<A, B>(a: A, b: B): Graph<A, F> | Graph<B, F>
909 or<A, B, C>(a: A, b: B, c: C): Graph<A, F> | Graph<B, F> | Graph<C, F>
910 or<A, B, C, D>(a: A, b: B, c: C, d: D): Graph<A, F> | Graph<B, F> | Graph<C, F> | Graph<D, F>
911 or<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): Graph<A, F> | Graph<B, F> | Graph<C, F> | Graph<D, F> | Graph<E, F>
912 or<A, B, C, D, E, FF>(
913 a: A,
914 b: B,
915 c: C,
916 d: D,
917 e: E,
918 f: FF
919 ): Graph<A, F> | Graph<B, F> | Graph<C, F> | Graph<D, F> | Graph<E, F> | Graph<FF, F>
920 or<A>(...args: A[]): Graph<A, F>
921
922 /**
923 * Logical operand and.
924 */
925 and<A>(a: A): Graph<A, F>
926 and<A, B>(a: A, b: B): Graph<B, F>
927 and<A, B, C>(a: A, b: B, c: C): Graph<C, F>
928 and<A, B, C, D>(a: A, b: B, c: C, d: D): Graph<D, F>
929 and<A, B, C, D, E>(a: A, b: B, c: C, d: D, e: E): Graph<E, F>
930 and<A, B, C, D, E, FF>(a: A, b: B, c: C, d: D, e: E, f: FF): Graph<FF, F>
931 and<A>(...args: A[]): Graph<A, F>
932 /**
933 * Declare actions which can be triggered on your state to change it (use arg0/arg1/arg2 - to define placeholders in the path).
934 * @example
935 * const { root, setter, arg0 } = require('carmi')
936 * const instance = createInstance({
937 * setItem: setter(arg0),
938 * output: root.any((value, index) => value.eq(2))
939 * }, [3, 2, 1]);
940 * console.log(instance.output) //true
941 * instance.setItem(1, 3)
942 * instance.output //false
943 */
944 setter<Path extends PathSegment[]>(...path: Path): SetterExpression<Schema, Path, F>
945
946 /**
947 * Declare actions which can be triggered on your state to change it (use arg0/arg1/arg2 - to define placeholders in the path).
948 */
949 splice<Path extends PathSegment[]>(...path: Path): SpliceExpression<Schema, Path, F>
950
951 /**
952 * Declare a setter that adds an element to the end of an array. The setter will create the array if one doesn't exist.
953 */
954 push<Path extends PathSegment[]>(...path: Path): PushExpression<Schema, Path, F>
955
956 /**
957 * Calls the function name passed from the function library while passing current value as the first argument, and then the provided args.
958 */
959 call<FunctionName extends keyof F>(
960 func: FunctionName,
961 ...args: Argument<Parameters<F[FunctionName]>[number]>[]
962 ): Graph<ReturnType<F[FunctionName]>, F>
963
964 /**
965 * See the docs for [`effect(func, args)`](api.html#effectfunc-args-1) in the **Graph** section of this API reference.
966 */
967 effect<FunctionName extends keyof F>(
968 func: FunctionName,
969 ...args: Argument<Parameters<F[FunctionName]>[number]>[]
970 ): Graph<ReturnType<F[FunctionName]>, F>
971
972 /**
973 * Creates a function that invokes `functionName` from the function library with args prepended to the arguments it receives.
974 */
975 bind<FunctionName extends keyof F>(func: FunctionName): FunctionGraph<BoundFunction<F[FunctionName]>, F>
976 bind<FunctionName extends keyof F, A>(func: FunctionName, a: A): FunctionGraph<BoundFunction<F[FunctionName], A>, F>
977 bind<FunctionName extends keyof F, A = Parameters<F[FunctionName]>[0], B = Parameters<F[FunctionName]>[1]>(
978 func: FunctionName,
979 a: A,
980 b: B
981 ): FunctionGraph<BoundFunction<F[FunctionName], A, B>, F>
982 bind<
983 FunctionName extends keyof F,
984 A = Parameters<F[FunctionName]>[0],
985 B = Parameters<F[FunctionName]>[1],
986 C = Parameters<F[FunctionName]>[2]
987 >(
988 func: FunctionName,
989 a: A,
990 b: B,
991 c: C
992 ): FunctionGraph<BoundFunction<F[FunctionName], A, B, C>, F>
993 bind<
994 FunctionName extends keyof F,
995 A = Parameters<F[FunctionName]>[0],
996 B = Parameters<F[FunctionName]>[1],
997 C = Parameters<F[FunctionName]>[2],
998 D = Parameters<F[FunctionName]>[3]
999 >(
1000 func: FunctionName,
1001 a: A,
1002 b: B,
1003 c: C,
1004 d: D
1005 ): FunctionGraph<BoundFunction<F[FunctionName], A, B, C, D>, F>
1006 bind<
1007 FunctionName extends keyof F,
1008 A = Parameters<F[FunctionName]>[0],
1009 B = Parameters<F[FunctionName]>[1],
1010 C = Parameters<F[FunctionName]>[2],
1011 D = Parameters<F[FunctionName]>[3],
1012 E = Parameters<F[FunctionName]>[4]
1013 >(
1014 func: FunctionName,
1015 a: A,
1016 b: B,
1017 c: C,
1018 d: D,
1019 e: E
1020 ): FunctionGraph<BoundFunction<F[FunctionName], A, B, C, D, E>, F>
1021
1022 /**
1023 * Defines a projection to be implemented later in the code using the [`implement(iface, name)`](api.html#implementiface-name) method.
1024 * @param name used for debug only
1025 */
1026 abstract(name: string): Graph<unknown, F>
1027
1028 /**
1029 * Uses a previously declared abstract clause and assigns an actual value to the named abstract.
1030 */
1031 implement(iface: Graph<unknown, F>, name: string): void
1032
1033 /**
1034 * A debug feature that allows to name the actual projection functions on the carmi root.
1035 */
1036 withName<T>(name: string, g: T): T
1037
1038 /**
1039 * This api creates a string using carmi models and the template string method.
1040 * @example
1041 * const { root, template } = require('carmi');
1042 * const instance = createInstance({
1043 * output: template`Second array item is:${root.get(1)}.`
1044 * }, [3, 2, 1]);
1045 * instance.output //Second array item is:2.
1046 */
1047 template(template: TemplateStringsArray, ...placeholders: any[]): StringGraph<string, F>
1048
1049 arg0: Token
1050 arg1: Token
1051 arg2: Token
1052}
1053
1054export const bind: CarmiAPI['bind']
1055export const or: CarmiAPI['or']
1056export const and: CarmiAPI['and']
1057export const setter: CarmiAPI['setter']
1058export const splice: CarmiAPI['splice']
1059export const push: CarmiAPI['push']
1060export const abstract: CarmiAPI['abstract']
1061export const implement: CarmiAPI['implement']
1062export const effect: CarmiAPI['effect']
1063export const call: CarmiAPI['call']
1064export const chain: CarmiAPI['chain']
1065export const root: CarmiAPI['root']
1066export const template: CarmiAPI['template']
1067export const arg0: CarmiAPI['arg0']
1068export const arg1: CarmiAPI['arg1']
1069export const arg2: CarmiAPI['arg2']
1070
1071declare const carmiDefaultAPI: CarmiAPI
1072export default carmiDefaultAPI
1073
1074export function withSchema<Schema extends object, F extends FunctionLibrary>(
1075 model?: Schema,
1076 functions?: F
1077): CarmiAPI<Schema, F>
1078export function compile(transformations: object, options?: object): string
1079
\No newline at end of file