UNPKG

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