@angular-wave/angular.ts 0.0.11 → 0.0.13

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.
Files changed (79) hide show
  1. package/dist/angular-ts.esm.js +1 -1
  2. package/dist/angular-ts.umd.js +1 -1
  3. package/package.json +4 -1
  4. package/src/exts/messages.md +30 -30
  5. package/src/index.js +1 -0
  6. package/src/public.js +2 -0
  7. package/src/router/adapter/directives/stateDirectives.js +695 -0
  8. package/src/router/adapter/directives/viewDirective.js +514 -0
  9. package/src/router/adapter/injectables.js +314 -0
  10. package/src/router/adapter/interface.js +1 -0
  11. package/src/router/adapter/locationServices.js +84 -0
  12. package/src/router/adapter/services.js +126 -0
  13. package/src/router/adapter/stateFilters.js +43 -0
  14. package/src/router/adapter/stateProvider.js +137 -0
  15. package/src/router/adapter/statebuilders/onEnterExitRetain.js +30 -0
  16. package/src/router/adapter/statebuilders/views.js +146 -0
  17. package/src/router/adapter/templateFactory.js +218 -0
  18. package/src/router/adapter/viewScroll.js +31 -0
  19. package/src/router/core/common/common.js +496 -0
  20. package/src/router/core/common/coreservices.js +15 -0
  21. package/src/router/core/common/glob.js +75 -0
  22. package/src/router/core/common/hof.js +194 -0
  23. package/src/router/core/common/predicates.js +44 -0
  24. package/src/router/core/common/queue.js +41 -0
  25. package/src/router/core/common/safeConsole.js +38 -0
  26. package/src/router/core/common/strings.js +141 -0
  27. package/src/router/core/common/trace.js +232 -0
  28. package/src/router/core/globals.js +29 -0
  29. package/src/router/core/hooks/coreResolvables.js +33 -0
  30. package/src/router/core/hooks/ignoredTransition.js +25 -0
  31. package/src/router/core/hooks/invalidTransition.js +14 -0
  32. package/src/router/core/hooks/lazyLoad.js +102 -0
  33. package/src/router/core/hooks/onEnterExitRetain.js +55 -0
  34. package/src/router/core/hooks/redirectTo.js +36 -0
  35. package/src/router/core/hooks/resolve.js +57 -0
  36. package/src/router/core/hooks/updateGlobals.js +30 -0
  37. package/src/router/core/hooks/url.js +25 -0
  38. package/src/router/core/hooks/views.js +39 -0
  39. package/src/router/core/interface.js +3 -0
  40. package/src/router/core/params/README.md +8 -0
  41. package/src/router/core/params/param.js +232 -0
  42. package/src/router/core/params/paramType.js +139 -0
  43. package/src/router/core/params/paramTypes.js +163 -0
  44. package/src/router/core/params/stateParams.js +35 -0
  45. package/src/router/core/path/pathNode.js +77 -0
  46. package/src/router/core/path/pathUtils.js +199 -0
  47. package/src/router/core/resolve/interface.js +10 -0
  48. package/src/router/core/resolve/resolvable.js +124 -0
  49. package/src/router/core/resolve/resolveContext.js +211 -0
  50. package/src/router/core/router.js +203 -0
  51. package/src/router/core/state/README.md +21 -0
  52. package/src/router/core/state/stateBuilder.js +332 -0
  53. package/src/router/core/state/stateMatcher.js +65 -0
  54. package/src/router/core/state/stateObject.js +117 -0
  55. package/src/router/core/state/stateQueueManager.js +89 -0
  56. package/src/router/core/state/stateRegistry.js +175 -0
  57. package/src/router/core/state/stateService.js +592 -0
  58. package/src/router/core/state/targetState.js +159 -0
  59. package/src/router/core/transition/hookBuilder.js +127 -0
  60. package/src/router/core/transition/hookRegistry.js +175 -0
  61. package/src/router/core/transition/interface.js +14 -0
  62. package/src/router/core/transition/rejectFactory.js +122 -0
  63. package/src/router/core/transition/transition.js +739 -0
  64. package/src/router/core/transition/transitionEventType.js +27 -0
  65. package/src/router/core/transition/transitionHook.js +199 -0
  66. package/src/router/core/transition/transitionService.js +311 -0
  67. package/src/router/core/url/interface.js +1 -0
  68. package/src/router/core/url/urlConfig.js +165 -0
  69. package/src/router/core/url/urlMatcher.js +548 -0
  70. package/src/router/core/url/urlMatcherFactory.js +123 -0
  71. package/src/router/core/url/urlRouter.js +115 -0
  72. package/src/router/core/url/urlRule.js +202 -0
  73. package/src/router/core/url/urlRules.js +348 -0
  74. package/src/router/core/url/urlService.js +268 -0
  75. package/src/router/core/view/interface.js +1 -0
  76. package/src/router/core/view/view.js +312 -0
  77. package/src/router/router.js +58 -0
  78. package/test/module-test.html +6 -2
  79. package/test/module-test.js +0 -0
@@ -0,0 +1,194 @@
1
+ /**
2
+ * Higher order functions
3
+ *
4
+ * These utility functions are exported, but are subject to change without notice.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ /**
9
+ * Returns a new function for [Partial Application](https://en.wikipedia.org/wiki/Partial_application) of the original function.
10
+ *
11
+ * Given a function with N parameters, returns a new function that supports partial application.
12
+ * The new function accepts anywhere from 1 to N parameters. When that function is called with M parameters,
13
+ * where M is less than N, it returns a new function that accepts the remaining parameters. It continues to
14
+ * accept more parameters until all N parameters have been supplied.
15
+ *
16
+ *
17
+ * This contrived example uses a partially applied function as an predicate, which returns true
18
+ * if an object is found in both arrays.
19
+ * @example
20
+ * ```
21
+ * // returns true if an object is in both of the two arrays
22
+ * function inBoth(array1, array2, object) {
23
+ * return array1.indexOf(object) !== -1 &&
24
+ * array2.indexOf(object) !== 1;
25
+ * }
26
+ * let obj1, obj2, obj3, obj4, obj5, obj6, obj7
27
+ * let foos = [obj1, obj3]
28
+ * let bars = [obj3, obj4, obj5]
29
+ *
30
+ * // A curried "copy" of inBoth
31
+ * let curriedInBoth = curry(inBoth);
32
+ * // Partially apply both the array1 and array2
33
+ * let inFoosAndBars = curriedInBoth(foos, bars);
34
+ *
35
+ * // Supply the final argument; since all arguments are
36
+ * // supplied, the original inBoth function is then called.
37
+ * let obj1InBoth = inFoosAndBars(obj1); // false
38
+ *
39
+ * // Use the inFoosAndBars as a predicate.
40
+ * // Filter, on each iteration, supplies the final argument
41
+ * let allObjs = [ obj1, obj2, obj3, obj4, obj5, obj6, obj7 ];
42
+ * let foundInBoth = allObjs.filter(inFoosAndBars); // [ obj3 ]
43
+ *
44
+ * ```
45
+ *
46
+ * @param fn
47
+ * @returns {*|function(): (*|any)}
48
+ */
49
+ export function curry(fn) {
50
+ return function curried() {
51
+ if (arguments.length >= fn.length) {
52
+ return fn.apply(this, arguments);
53
+ }
54
+ const args = Array.prototype.slice.call(arguments);
55
+ return curried.bind(this, ...args);
56
+ };
57
+ }
58
+ /**
59
+ * Given a varargs list of functions, returns a function that composes the argument functions, right-to-left
60
+ * given: f(x), g(x), h(x)
61
+ * let composed = compose(f,g,h)
62
+ * then, composed is: f(g(h(x)))
63
+ */
64
+ export function compose() {
65
+ const args = arguments;
66
+ const start = args.length - 1;
67
+ return function () {
68
+ let i = start,
69
+ result = args[start].apply(this, arguments);
70
+ while (i--) result = args[i].call(this, result);
71
+ return result;
72
+ };
73
+ }
74
+ /**
75
+ * Given a varargs list of functions, returns a function that is composes the argument functions, left-to-right
76
+ * given: f(x), g(x), h(x)
77
+ * let piped = pipe(f,g,h);
78
+ * then, piped is: h(g(f(x)))
79
+ */
80
+ export function pipe(...funcs) {
81
+ return compose.apply(null, [].slice.call(arguments).reverse());
82
+ }
83
+ /**
84
+ * Given a property name, returns a function that returns that property from an object
85
+ * let obj = { foo: 1, name: "blarg" };
86
+ * let getName = prop("name");
87
+ * getName(obj) === "blarg"
88
+ */
89
+ export const prop = (name) => (obj) => obj && obj[name];
90
+ /**
91
+ * Given a property name and a value, returns a function that returns a boolean based on whether
92
+ * the passed object has a property that matches the value
93
+ * let obj = { foo: 1, name: "blarg" };
94
+ * let getName = propEq("name", "blarg");
95
+ * getName(obj) === true
96
+ */
97
+ export const propEq = curry((name, _val, obj) => obj && obj[name] === _val);
98
+ /**
99
+ * Given a dotted property name, returns a function that returns a nested property from an object, or undefined
100
+ * let obj = { id: 1, nestedObj: { foo: 1, name: "blarg" }, };
101
+ * let getName = prop("nestedObj.name");
102
+ * getName(obj) === "blarg"
103
+ * let propNotFound = prop("this.property.doesnt.exist");
104
+ * propNotFound(obj) === undefined
105
+ */
106
+ export const parse = (name) => pipe.apply(null, name.split(".").map(prop));
107
+ /**
108
+ * Given a function that returns a truthy or falsey value, returns a
109
+ * function that returns the opposite (falsey or truthy) value given the same inputs
110
+ */
111
+ export const not =
112
+ (fn) =>
113
+ (...args) =>
114
+ !fn.apply(null, args);
115
+ /**
116
+ * Given two functions that return truthy or falsey values, returns a function that returns truthy
117
+ * if both functions return truthy for the given arguments
118
+ */
119
+ export function and(fn1, fn2) {
120
+ return (...args) => fn1.apply(null, args) && fn2.apply(null, args);
121
+ }
122
+ /**
123
+ * Given two functions that return truthy or falsey values, returns a function that returns truthy
124
+ * if at least one of the functions returns truthy for the given arguments
125
+ */
126
+ export function or(fn1, fn2) {
127
+ return (...args) => fn1.apply(null, args) || fn2.apply(null, args);
128
+ }
129
+ /**
130
+ * Check if all the elements of an array match a predicate function
131
+ *
132
+ * @param fn1 a predicate function `fn1`
133
+ * @returns a function which takes an array and returns true if `fn1` is true for all elements of the array
134
+ */
135
+ export const all = (fn1) => (arr) => arr.reduce((b, x) => b && !!fn1(x), true);
136
+ // tslint:disable-next-line:variable-name
137
+ export const any = (fn1) => (arr) => arr.reduce((b, x) => b || !!fn1(x), false);
138
+ /** Given a class, returns a Predicate function that returns true if the object is of that class */
139
+ export const is = (ctor) => (obj) =>
140
+ (obj != null && obj.constructor === ctor) || obj instanceof ctor;
141
+ /** Given a value, returns a Predicate function that returns true if another value is === equal to the original value */
142
+ export const eq = (value) => (other) => value === other;
143
+ /** Given a value, returns a function which returns the value */
144
+ export const val = (v) => () => v;
145
+ export function invoke(fnName, args) {
146
+ return (obj) => obj[fnName].apply(obj, args);
147
+ }
148
+ /**
149
+ * Sorta like Pattern Matching (a functional programming conditional construct)
150
+ *
151
+ * See http://c2.com/cgi/wiki?PatternMatching
152
+ *
153
+ * This is a conditional construct which allows a series of predicates and output functions
154
+ * to be checked and then applied. Each predicate receives the input. If the predicate
155
+ * returns truthy, then its matching output function (mapping function) is provided with
156
+ * the input and, then the result is returned.
157
+ *
158
+ * Each combination (2-tuple) of predicate + output function should be placed in an array
159
+ * of size 2: [ predicate, mapFn ]
160
+ *
161
+ * These 2-tuples should be put in an outer array.
162
+ *
163
+ * @example
164
+ * ```
165
+ *
166
+ * // Here's a 2-tuple where the first element is the isString predicate
167
+ * // and the second element is a function that returns a description of the input
168
+ * let firstTuple = [ angular.isString, (input) => `Heres your string ${input}` ];
169
+ *
170
+ * // Second tuple: predicate "isNumber", mapfn returns a description
171
+ * let secondTuple = [ angular.isNumber, (input) => `(${input}) That's a number!` ];
172
+ *
173
+ * let third = [ (input) => input === null, (input) => `Oh, null...` ];
174
+ *
175
+ * let fourth = [ (input) => input === undefined, (input) => `notdefined` ];
176
+ *
177
+ * let descriptionOf = pattern([ firstTuple, secondTuple, third, fourth ]);
178
+ *
179
+ * console.log(descriptionOf(undefined)); // 'notdefined'
180
+ * console.log(descriptionOf(55)); // '(55) That's a number!'
181
+ * console.log(descriptionOf("foo")); // 'Here's your string foo'
182
+ * ```
183
+ *
184
+ * @param struct A 2D array. Each element of the array should be an array, a 2-tuple,
185
+ * with a Predicate and a mapping/output function
186
+ * @returns {function(any): *}
187
+ */
188
+ export function pattern(struct) {
189
+ return function (x) {
190
+ for (let i = 0; i < struct.length; i++) {
191
+ if (struct[i][0](x)) return struct[i][1](x);
192
+ }
193
+ };
194
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Predicates
3
+ *
4
+ * These predicates return true/false based on the input.
5
+ * Although these functions are exported, they are subject to change without notice.
6
+ *
7
+ * @packageDocumentation
8
+ */
9
+ import { and, not, pipe, prop, or } from "./hof";
10
+ const toStr = Object.prototype.toString;
11
+ const tis = (t) => (x) => typeof x === t;
12
+ export const isUndefined = tis("undefined");
13
+ export const isDefined = not(isUndefined);
14
+ export const isNull = (o) => o === null;
15
+ export const isNullOrUndefined = or(isNull, isUndefined);
16
+ export const isFunction = tis("function");
17
+ export const isNumber = tis("number");
18
+ export const isString = tis("string");
19
+ export const isObject = (x) => x !== null && typeof x === "object";
20
+ export const isArray = Array.isArray;
21
+ export const isDate = (x) => toStr.call(x) === "[object Date]";
22
+ export const isRegExp = (x) => toStr.call(x) === "[object RegExp]";
23
+ /**
24
+ * Predicate which checks if a value is injectable
25
+ *
26
+ * A value is "injectable" if it is a function, or if it is an ng1 array-notation-style array
27
+ * where all the elements in the array are Strings, except the last one, which is a Function
28
+ */
29
+ export function isInjectable(val) {
30
+ if (isArray(val) && val.length) {
31
+ const head = val.slice(0, -1),
32
+ tail = val.slice(-1);
33
+ return !(
34
+ head.filter(not(isString)).length || tail.filter(not(isFunction)).length
35
+ );
36
+ }
37
+ return isFunction(val);
38
+ }
39
+ /**
40
+ * Predicate which checks if a value looks like a Promise
41
+ *
42
+ * It is probably a Promise if it's an object, and it has a `then` property which is a Function
43
+ */
44
+ export const isPromise = and(isObject, pipe(prop("then"), isFunction));
@@ -0,0 +1,41 @@
1
+ import { pushTo } from "./common";
2
+ export class Queue {
3
+ constructor(_items = [], _limit = null) {
4
+ this._items = _items;
5
+ this._limit = _limit;
6
+ this._evictListeners = [];
7
+ this.onEvict = pushTo(this._evictListeners);
8
+ }
9
+ enqueue(item) {
10
+ const items = this._items;
11
+ items.push(item);
12
+ if (this._limit && items.length > this._limit) this.evict();
13
+ return item;
14
+ }
15
+ evict() {
16
+ const item = this._items.shift();
17
+ this._evictListeners.forEach((fn) => fn(item));
18
+ return item;
19
+ }
20
+ dequeue() {
21
+ if (this.size()) return this._items.splice(0, 1)[0];
22
+ }
23
+ clear() {
24
+ const current = this._items;
25
+ this._items = [];
26
+ return current;
27
+ }
28
+ size() {
29
+ return this._items.length;
30
+ }
31
+ remove(item) {
32
+ const idx = this._items.indexOf(item);
33
+ return idx > -1 && this._items.splice(idx, 1)[0];
34
+ }
35
+ peekTail() {
36
+ return this._items[this._items.length - 1];
37
+ }
38
+ peekHead() {
39
+ if (this.size()) return this._items[0];
40
+ }
41
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * workaround for missing console object in IE9 when dev tools haven't been opened o_O
3
+ * @packageDocumentation
4
+ */
5
+ /* tslint:disable:no-console */
6
+ import { noop } from "./common";
7
+ const noopConsoleStub = { log: noop, error: noop, table: noop };
8
+ function ie9Console(console) {
9
+ const bound = (fn) => Function.prototype.bind.call(fn, console);
10
+ return {
11
+ log: bound(console.log),
12
+ error: bound(console.log),
13
+ table: bound(console.log),
14
+ };
15
+ }
16
+ function fallbackConsole(console) {
17
+ const log = console.log.bind(console);
18
+ const error = console.error ? console.error.bind(console) : log;
19
+ const table = console.table ? console.table.bind(console) : log;
20
+ return { log, error, table };
21
+ }
22
+ function getSafeConsole() {
23
+ // @ts-ignore
24
+ const isIE9 =
25
+ typeof document !== "undefined" &&
26
+ document.documentMode &&
27
+ document.documentMode === 9;
28
+ if (isIE9) {
29
+ return window && window.console
30
+ ? ie9Console(window.console)
31
+ : noopConsoleStub;
32
+ } else if (!console.table || !console.error) {
33
+ return fallbackConsole(console);
34
+ } else {
35
+ return console;
36
+ }
37
+ }
38
+ export const safeConsole = getSafeConsole();
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Functions that manipulate strings
3
+ *
4
+ * Although these functions are exported, they are subject to change without notice.
5
+ *
6
+ * @packageDocumentation
7
+ */
8
+ import {
9
+ isArray,
10
+ isFunction,
11
+ isInjectable,
12
+ isNull,
13
+ isObject,
14
+ isPromise,
15
+ isString,
16
+ isUndefined,
17
+ } from "./predicates";
18
+ import { Rejection } from "../transition/rejectFactory";
19
+ import { identity, pushR, tail } from "./common";
20
+ import { pattern, val } from "./hof";
21
+ /**
22
+ * Returns a string shortened to a maximum length
23
+ *
24
+ * If the string is already less than the `max` length, return the string.
25
+ * Else return the string, shortened to `max - 3` and append three dots ("...").
26
+ *
27
+ * @param max the maximum length of the string to return
28
+ * @param str the input string
29
+ */
30
+ export function maxLength(max, str) {
31
+ if (str.length <= max) return str;
32
+ return str.substr(0, max - 3) + "...";
33
+ }
34
+ /**
35
+ * Returns a string, with spaces added to the end, up to a desired str length
36
+ *
37
+ * If the string is already longer than the desired length, return the string.
38
+ * Else returns the string, with extra spaces on the end, such that it reaches `length` characters.
39
+ *
40
+ * @param length the desired length of the string to return
41
+ * @param str the input string
42
+ */
43
+ export function padString(length, str) {
44
+ while (str.length < length) str += " ";
45
+ return str;
46
+ }
47
+ export function kebobString(camelCase) {
48
+ return camelCase
49
+ .replace(/^([A-Z])/, ($1) => $1.toLowerCase()) // replace first char
50
+ .replace(/([A-Z])/g, ($1) => "-" + $1.toLowerCase()); // replace rest
51
+ }
52
+ export function functionToString(fn) {
53
+ const fnStr = fnToString(fn);
54
+ const namedFunctionMatch = fnStr.match(/^(function [^ ]+\([^)]*\))/);
55
+ const toStr = namedFunctionMatch ? namedFunctionMatch[1] : fnStr;
56
+ const fnName = fn["name"] || "";
57
+ if (fnName && toStr.match(/function \(/)) {
58
+ return "function " + fnName + toStr.substr(9);
59
+ }
60
+ return toStr;
61
+ }
62
+ export function fnToString(fn) {
63
+ const _fn = isArray(fn) ? fn.slice(-1)[0] : fn;
64
+ return (_fn && _fn.toString()) || "undefined";
65
+ }
66
+ export function stringify(o) {
67
+ const seen = [];
68
+ const isRejection = Rejection.isRejectionPromise;
69
+ const hasToString = (obj) =>
70
+ isObject(obj) &&
71
+ !isArray(obj) &&
72
+ obj.constructor !== Object &&
73
+ isFunction(obj.toString);
74
+ const stringifyPattern = pattern([
75
+ [isUndefined, val("undefined")],
76
+ [isNull, val("null")],
77
+ [isPromise, val("[Promise]")],
78
+ [isRejection, (x) => x._transitionRejection.toString()],
79
+ [hasToString, (x) => x.toString()],
80
+ [isInjectable, functionToString],
81
+ [val(true), identity],
82
+ ]);
83
+ function format(value) {
84
+ if (isObject(value)) {
85
+ if (seen.indexOf(value) !== -1) return "[circular ref]";
86
+ seen.push(value);
87
+ }
88
+ return stringifyPattern(value);
89
+ }
90
+ if (isUndefined(o)) {
91
+ // Workaround for IE & Edge Spec incompatibility where replacer function would not be called when JSON.stringify
92
+ // is given `undefined` as value. To work around that, we simply detect `undefined` and bail out early by
93
+ // manually stringifying it.
94
+ return format(o);
95
+ }
96
+ return JSON.stringify(o, (key, value) => format(value)).replace(/\\"/g, '"');
97
+ }
98
+ /** Returns a function that splits a string on a character or substring */
99
+ export const beforeAfterSubstr = (char) => (str) => {
100
+ if (!str) return ["", ""];
101
+ const idx = str.indexOf(char);
102
+ if (idx === -1) return [str, ""];
103
+ return [str.substr(0, idx), str.substr(idx + 1)];
104
+ };
105
+ export const hostRegex = new RegExp("^(?:[a-z]+:)?//[^/]+/");
106
+ export const stripLastPathElement = (str) => str.replace(/\/[^/]*$/, "");
107
+ export const splitHash = beforeAfterSubstr("#");
108
+ export const splitQuery = beforeAfterSubstr("?");
109
+ export const splitEqual = beforeAfterSubstr("=");
110
+ export const trimHashVal = (str) => (str ? str.replace(/^#/, "") : "");
111
+ /**
112
+ * Splits on a delimiter, but returns the delimiters in the array
113
+ *
114
+ * #### Example:
115
+ * ```js
116
+ * var splitOnSlashes = splitOnDelim('/');
117
+ * splitOnSlashes("/foo"); // ["/", "foo"]
118
+ * splitOnSlashes("/foo/"); // ["/", "foo", "/"]
119
+ * ```
120
+ */
121
+ export function splitOnDelim(delim) {
122
+ const re = new RegExp("(" + delim + ")", "g");
123
+ return (str) => str.split(re).filter(identity);
124
+ }
125
+ /**
126
+ * Reduce fn that joins neighboring strings
127
+ *
128
+ * Given an array of strings, returns a new array
129
+ * where all neighboring strings have been joined.
130
+ *
131
+ * #### Example:
132
+ * ```js
133
+ * let arr = ["foo", "bar", 1, "baz", "", "qux" ];
134
+ * arr.reduce(joinNeighborsR, []) // ["foobar", 1, "bazqux" ]
135
+ * ```
136
+ */
137
+ export function joinNeighborsR(acc, x) {
138
+ if (isString(tail(acc)) && isString(x))
139
+ return acc.slice(0, -1).concat(tail(acc) + x);
140
+ return pushR(acc, x);
141
+ }
@@ -0,0 +1,232 @@
1
+ /**
2
+ * # Transition tracing (debug)
3
+ *
4
+ * Enable transition tracing to print transition information to the console,
5
+ * in order to help debug your application.
6
+ * Tracing logs detailed information about each Transition to your console.
7
+ *
8
+ * To enable tracing, import the [[Trace]] singleton and enable one or more categories.
9
+ *
10
+ * ### ES6
11
+ * ```js
12
+ * import {trace} from "@uirouter/core/index";
13
+ * trace.enable(1, 5); // TRANSITION and VIEWCONFIG
14
+ * ```
15
+ *
16
+ * ### CJS
17
+ * ```js
18
+ * let trace = require("@uirouter/core").trace;
19
+ * trace.enable("TRANSITION", "VIEWCONFIG");
20
+ * ```
21
+ *
22
+ * ### Globals
23
+ * ```js
24
+ * let trace = window["@uirouter/core"].trace;
25
+ * trace.enable(); // Trace everything (very verbose)
26
+ * ```
27
+ *
28
+ * ### Angular 1:
29
+ * ```js
30
+ * app.run($trace => $trace.enable());
31
+ * ```
32
+ *
33
+ * @packageDocumentation
34
+ */
35
+ import { parse } from "../common/hof";
36
+ import { isNumber } from "../common/predicates";
37
+ import { stringify, functionToString, maxLength, padString } from "./strings";
38
+ import { safeConsole } from "./safeConsole";
39
+ function uiViewString(uiview) {
40
+ if (!uiview) return "ui-view (defunct)";
41
+ const state = uiview.creationContext
42
+ ? uiview.creationContext.name || "(root)"
43
+ : "(none)";
44
+ return `[ui-view#${uiview.id} ${uiview.$type}:${uiview.fqn} (${uiview.name}@${state})]`;
45
+ }
46
+ const viewConfigString = (viewConfig) => {
47
+ const view = viewConfig.viewDecl;
48
+ const state = view.$context.name || "(root)";
49
+ return `[View#${viewConfig.$id} from '${state}' state]: target ui-view: '${view.$uiViewName}@${view.$uiViewContextAnchor}'`;
50
+ };
51
+ function normalizedCat(input) {
52
+ return isNumber(input) ? Category[input] : Category[Category[input]];
53
+ }
54
+ /**
55
+ * Trace categories Enum
56
+ *
57
+ * Enable or disable a category using [[Trace.enable]] or [[Trace.disable]]
58
+ *
59
+ * `trace.enable(Category.TRANSITION)`
60
+ *
61
+ * These can also be provided using a matching string, or position ordinal
62
+ *
63
+ * `trace.enable("TRANSITION")`
64
+ *
65
+ * `trace.enable(1)`
66
+ */
67
+ var Category;
68
+ (function (Category) {
69
+ Category[(Category["RESOLVE"] = 0)] = "RESOLVE";
70
+ Category[(Category["TRANSITION"] = 1)] = "TRANSITION";
71
+ Category[(Category["HOOK"] = 2)] = "HOOK";
72
+ Category[(Category["UIVIEW"] = 3)] = "UIVIEW";
73
+ Category[(Category["VIEWCONFIG"] = 4)] = "VIEWCONFIG";
74
+ })(Category || (Category = {}));
75
+ export { Category };
76
+ const _tid = parse("$id");
77
+ const _rid = parse("router.$id");
78
+ const transLbl = (trans) => `Transition #${_tid(trans)}-${_rid(trans)}`;
79
+ /**
80
+ * Prints UI-Router Transition trace information to the console.
81
+ */
82
+ export class Trace {
83
+ /** @internal */
84
+ constructor() {
85
+ /** @internal */
86
+ this._enabled = {};
87
+ this.approximateDigests = 0;
88
+ }
89
+ /** @internal */
90
+ _set(enabled, categories) {
91
+ if (!categories.length) {
92
+ categories = Object.keys(Category)
93
+ .map((k) => parseInt(k, 10))
94
+ .filter((k) => !isNaN(k))
95
+ .map((key) => Category[key]);
96
+ }
97
+ categories
98
+ .map(normalizedCat)
99
+ .forEach((category) => (this._enabled[category] = enabled));
100
+ }
101
+ enable(...categories) {
102
+ this._set(true, categories);
103
+ }
104
+ disable(...categories) {
105
+ this._set(false, categories);
106
+ }
107
+ /**
108
+ * Retrieves the enabled stateus of a [[Category]]
109
+ *
110
+ * ```js
111
+ * trace.enabled("VIEWCONFIG"); // true or false
112
+ * ```
113
+ *
114
+ * @returns boolean true if the category is enabled
115
+ */
116
+ enabled(category) {
117
+ return !!this._enabled[normalizedCat(category)];
118
+ }
119
+ /** @internal called by ui-router code */
120
+ traceTransitionStart(trans) {
121
+ if (!this.enabled(Category.TRANSITION)) return;
122
+ safeConsole.log(`${transLbl(trans)}: Started -> ${stringify(trans)}`);
123
+ }
124
+ /** @internal called by ui-router code */
125
+ traceTransitionIgnored(trans) {
126
+ if (!this.enabled(Category.TRANSITION)) return;
127
+ safeConsole.log(`${transLbl(trans)}: Ignored <> ${stringify(trans)}`);
128
+ }
129
+ /** @internal called by ui-router code */
130
+ traceHookInvocation(step, trans, options) {
131
+ if (!this.enabled(Category.HOOK)) return;
132
+ const event = parse("traceData.hookType")(options) || "internal",
133
+ context =
134
+ parse("traceData.context.state.name")(options) ||
135
+ parse("traceData.context")(options) ||
136
+ "unknown",
137
+ name = functionToString(step.registeredHook.callback);
138
+ safeConsole.log(
139
+ `${transLbl(trans)}: Hook -> ${event} context: ${context}, ${maxLength(200, name)}`,
140
+ );
141
+ }
142
+ /** @internal called by ui-router code */
143
+ traceHookResult(hookResult, trans, transitionOptions) {
144
+ if (!this.enabled(Category.HOOK)) return;
145
+ safeConsole.log(
146
+ `${transLbl(trans)}: <- Hook returned: ${maxLength(200, stringify(hookResult))}`,
147
+ );
148
+ }
149
+ /** @internal called by ui-router code */
150
+ traceResolvePath(path, when, trans) {
151
+ if (!this.enabled(Category.RESOLVE)) return;
152
+ safeConsole.log(`${transLbl(trans)}: Resolving ${path} (${when})`);
153
+ }
154
+ /** @internal called by ui-router code */
155
+ traceResolvableResolved(resolvable, trans) {
156
+ if (!this.enabled(Category.RESOLVE)) return;
157
+ safeConsole.log(
158
+ `${transLbl(trans)}: <- Resolved ${resolvable} to: ${maxLength(200, stringify(resolvable.data))}`,
159
+ );
160
+ }
161
+ /** @internal called by ui-router code */
162
+ traceError(reason, trans) {
163
+ if (!this.enabled(Category.TRANSITION)) return;
164
+ safeConsole.log(
165
+ `${transLbl(trans)}: <- Rejected ${stringify(trans)}, reason: ${reason}`,
166
+ );
167
+ }
168
+ /** @internal called by ui-router code */
169
+ traceSuccess(finalState, trans) {
170
+ if (!this.enabled(Category.TRANSITION)) return;
171
+ safeConsole.log(
172
+ `${transLbl(trans)}: <- Success ${stringify(trans)}, final state: ${finalState.name}`,
173
+ );
174
+ }
175
+ /** @internal called by ui-router code */
176
+ traceUIViewEvent(event, viewData, extra = "") {
177
+ if (!this.enabled(Category.UIVIEW)) return;
178
+ safeConsole.log(
179
+ `ui-view: ${padString(30, event)} ${uiViewString(viewData)}${extra}`,
180
+ );
181
+ }
182
+ /** @internal called by ui-router code */
183
+ traceUIViewConfigUpdated(viewData, context) {
184
+ if (!this.enabled(Category.UIVIEW)) return;
185
+ this.traceUIViewEvent(
186
+ "Updating",
187
+ viewData,
188
+ ` with ViewConfig from context='${context}'`,
189
+ );
190
+ }
191
+ /** @internal called by ui-router code */
192
+ traceUIViewFill(viewData, html) {
193
+ if (!this.enabled(Category.UIVIEW)) return;
194
+ this.traceUIViewEvent("Fill", viewData, ` with: ${maxLength(200, html)}`);
195
+ }
196
+ /** @internal called by ui-router code */
197
+ traceViewSync(pairs) {
198
+ if (!this.enabled(Category.VIEWCONFIG)) return;
199
+ const uivheader = "uiview component fqn";
200
+ const cfgheader = "view config state (view name)";
201
+ const mapping = pairs
202
+ .map(({ uiView, viewConfig }) => {
203
+ const uiv = uiView && uiView.fqn;
204
+ const cfg =
205
+ viewConfig &&
206
+ `${viewConfig.viewDecl.$context.name}: (${viewConfig.viewDecl.$name})`;
207
+ return { [uivheader]: uiv, [cfgheader]: cfg };
208
+ })
209
+ .sort((a, b) => (a[uivheader] || "").localeCompare(b[uivheader] || ""));
210
+ safeConsole.table(mapping);
211
+ }
212
+ /** @internal called by ui-router code */
213
+ traceViewServiceEvent(event, viewConfig) {
214
+ if (!this.enabled(Category.VIEWCONFIG)) return;
215
+ safeConsole.log(`VIEWCONFIG: ${event} ${viewConfigString(viewConfig)}`);
216
+ }
217
+ /** @internal called by ui-router code */
218
+ traceViewServiceUIViewEvent(event, viewData) {
219
+ if (!this.enabled(Category.VIEWCONFIG)) return;
220
+ safeConsole.log(`VIEWCONFIG: ${event} ${uiViewString(viewData)}`);
221
+ }
222
+ }
223
+ /**
224
+ * The [[Trace]] singleton
225
+ *
226
+ * #### Example:
227
+ * ```js
228
+ * import {trace} from "@uirouter/core/index";
229
+ * trace.enable(1, 5);
230
+ * ```
231
+ */
232
+ export const trace = new Trace();