@panyam/tsutils 0.0.66 → 0.0.67
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.
- package/lib/cjs/apis/evapis.js +1 -1
- package/lib/cjs/apis/evapis.js.map +1 -1
- package/lib/cjs/apis/index.js +5 -1
- package/lib/cjs/apis/index.js.map +1 -1
- package/lib/cjs/apis/net.js.map +1 -1
- package/lib/cjs/comms/actors.js +5 -5
- package/lib/cjs/comms/actors.js.map +1 -1
- package/lib/cjs/comms/bus.d.ts +1 -2
- package/lib/cjs/comms/bus.js.map +1 -1
- package/lib/cjs/comms/events.d.ts +1 -1
- package/lib/cjs/comms/events.js.map +1 -1
- package/lib/cjs/decorators.js +1 -2
- package/lib/cjs/decorators.js.map +1 -1
- package/lib/cjs/dom.js +22 -19
- package/lib/cjs/dom.js.map +1 -1
- package/lib/cjs/geom.js.map +1 -1
- package/lib/cjs/index.js +5 -1
- package/lib/cjs/index.js.map +1 -1
- package/lib/cjs/list.js.map +1 -1
- package/lib/cjs/misc.js +8 -8
- package/lib/cjs/misc.js.map +1 -1
- package/lib/cjs/numberutils.js +3 -3
- package/lib/cjs/numberutils.js.map +1 -1
- package/lib/cjs/scrolling.d.ts +12 -23
- package/lib/cjs/scrolling.js +49 -104
- package/lib/cjs/scrolling.js.map +1 -1
- package/lib/cjs/streams.js +5 -6
- package/lib/cjs/streams.js.map +1 -1
- package/lib/cjs/timer.d.ts +1 -1
- package/lib/cjs/timer.js.map +1 -1
- package/lib/cjs/timeutils.js +7 -7
- package/lib/cjs/timeutils.js.map +1 -1
- package/lib/cjs/types.d.ts +6 -6
- package/lib/cjs/types.js +1 -2
- package/lib/cjs/types.js.map +1 -1
- package/lib/esm/apis/net.js.map +1 -1
- package/lib/esm/comms/actors.js.map +1 -1
- package/lib/esm/comms/bus.d.ts +1 -2
- package/lib/esm/comms/bus.js.map +1 -1
- package/lib/esm/comms/events.d.ts +1 -1
- package/lib/esm/comms/events.js.map +1 -1
- package/lib/esm/dom.js.map +1 -1
- package/lib/esm/geom.js.map +1 -1
- package/lib/esm/list.js.map +1 -1
- package/lib/esm/misc.js.map +1 -1
- package/lib/esm/numberutils.js.map +1 -1
- package/lib/esm/scrolling.d.ts +12 -23
- package/lib/esm/scrolling.js +47 -102
- package/lib/esm/scrolling.js.map +1 -1
- package/lib/esm/streams.js.map +1 -1
- package/lib/esm/timer.d.ts +1 -1
- package/lib/esm/timer.js.map +1 -1
- package/lib/esm/timeutils.js.map +1 -1
- package/lib/esm/types.d.ts +6 -6
- package/lib/esm/types.js.map +1 -1
- package/package.json +32 -32
package/lib/cjs/list.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport interface ListNode<V> {\n nextSibling: Nullable<V>;\n prevSibling: Nullable<V>;\n}\n\nclass MutableListNode<V> implements ListNode<MutableListNode<V>> {\n nextSibling: Nullable<MutableListNode<V>> = null;\n prevSibling: Nullable<MutableListNode<V>> = null;\n constructor(public value: V) {}\n}\n\n/**\n * A list implementation where the value itself contains next and prev pointers\n * so we do not need to create wrapper classes.\n */\nexport class ValueList<V extends ListNode<V>> {\n protected _firstChild: Nullable<V> = null;\n protected _lastChild: Nullable<V> = null;\n protected _size = 0;\n\n constructor(...values: V[]) {\n for (const v of values) this.pushBack(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n let tmp: V | null = this._firstChild;\n let count = 0;\n while (tmp != null) {\n if (method(tmp) == false) {\n break;\n }\n count++;\n tmp = tmp.nextSibling;\n }\n return count;\n }\n\n equals(another: ValueList<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n if (this.size != another.size) return false;\n let tmp = this.first;\n let tmp2 = another.first;\n for (; tmp != null && tmp2 != null; tmp = tmp.nextSibling, tmp2 = tmp2.nextSibling) {\n if (!eqlFunc(tmp, tmp2)) {\n return false;\n }\n }\n return tmp == null && tmp2 == null;\n }\n\n get isEmpty(): boolean {\n return this._size == 0;\n }\n\n get size(): number {\n return this._size;\n }\n\n get first(): Nullable<V> {\n return this._firstChild;\n }\n\n get last(): Nullable<V> {\n return this._lastChild;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n let tmp = this._lastChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.prevSibling;\n }\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n let tmp = this._firstChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.nextSibling;\n }\n }\n\n add(child: V, before: Nullable<V> = null): this {\n // Ensure that this node is not added anywhere else\n if (child.nextSibling != null || child.prevSibling != null) {\n throw new Error(\"New node already added to a list. Remove it first\");\n }\n child.nextSibling = child.prevSibling = null;\n this._size++;\n if (this._firstChild == null || this._lastChild == null) {\n this._firstChild = this._lastChild = child;\n } else if (before == null) {\n child.prevSibling = this._lastChild;\n child.nextSibling = null;\n this._lastChild.nextSibling = child;\n this._lastChild = child;\n } else if (before == this._firstChild) {\n child.nextSibling = before;\n child.prevSibling = null;\n this._firstChild.prevSibling = child;\n this._firstChild = child;\n } else {\n const prev = before.prevSibling;\n child.nextSibling = before;\n before.prevSibling = child;\n child.prevSibling = prev;\n if (prev != null) {\n prev.nextSibling = child;\n }\n }\n return this;\n }\n\n pushFront(value: V): this {\n return this.add(value, this._firstChild);\n }\n\n pushBack(value: V): this {\n return this.add(value);\n }\n\n /**\n * Removes a child node from this list.\n * It is upto the caller to ensure that this node indeed belongs\n * to this list otherwise deletion of a non belonging node could result\n * in undefined behaviour.\n */\n remove(child: V): this {\n const next = child.nextSibling;\n const prev = child.prevSibling;\n\n if (next == null) {\n this._lastChild = prev;\n if (prev == null) this._firstChild = null;\n } else {\n next.prevSibling = prev;\n }\n\n if (prev == null) {\n this._firstChild = next;\n if (next == null) this._lastChild = null;\n } else {\n prev.nextSibling = next;\n }\n\n this._size--;\n\n child.prevSibling = child.nextSibling = null;\n return this;\n }\n\n popBack(): V {\n if (this._lastChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._lastChild;\n this.remove(out);\n return out;\n }\n\n popFront(): V {\n if (this._firstChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._firstChild;\n this.remove(out);\n return out;\n }\n}\n\n/**\n * A list implementation where the values themselves need to be wrapper in a list node.\n * If values already have sibling node properties they can be direclty used\n * via ValueLists.\n */\nexport class List<V> {\n private container: ValueList<MutableListNode<V>>;\n\n constructor(...values: V[]) {\n this.container = new ValueList<MutableListNode<V>>();\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n return this.container.forEach((v) => method(v.value));\n }\n\n equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));\n }\n\n find(target: V): Nullable<MutableListNode<V>> {\n for (const v of this.container.values()) {\n if (target == v.value) {\n return v;\n }\n }\n return null;\n }\n\n get isEmpty(): boolean {\n return this.container.isEmpty;\n }\n\n get size(): number {\n return this.container.size;\n }\n\n get first(): Nullable<MutableListNode<V>> {\n return this.container.first;\n }\n\n get last(): Nullable<MutableListNode<V>> {\n return this.container.last;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n for (const v of this.container.reversedValues()) yield v.value;\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n for (const v of this.container.values()) yield v.value;\n }\n\n popBack(): V {\n return this.container.popBack().value;\n }\n\n popFront(): V {\n return this.container.popFront().value;\n }\n\n pushFront(value: V): this {\n return this.add(value, this.container.first);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n\n add(child: V, before: Nullable<MutableListNode<V>> = null): this {\n this.container.add(new MutableListNode(child), before);\n return this;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/list.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport interface ListNode<V> {\n nextSibling: Nullable<V>;\n prevSibling: Nullable<V>;\n}\n\nclass MutableListNode<V> implements ListNode<MutableListNode<V>> {\n nextSibling: Nullable<MutableListNode<V>> = null;\n prevSibling: Nullable<MutableListNode<V>> = null;\n constructor(public value: V) {}\n}\n\n/**\n * A list implementation where the value itself contains next and prev pointers\n * so we do not need to create wrapper classes.\n */\nexport class ValueList<V extends ListNode<V>> {\n protected _firstChild: Nullable<V> = null;\n protected _lastChild: Nullable<V> = null;\n protected _size = 0;\n\n constructor(...values: V[]) {\n for (const v of values) this.pushBack(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n let tmp: V | null = this._firstChild;\n let count = 0;\n while (tmp != null) {\n if (method(tmp) == false) {\n break;\n }\n count++;\n tmp = tmp.nextSibling;\n }\n return count;\n }\n\n equals(another: ValueList<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n if (this.size != another.size) return false;\n let tmp = this.first;\n let tmp2 = another.first;\n for (; tmp != null && tmp2 != null; tmp = tmp.nextSibling, tmp2 = tmp2.nextSibling) {\n if (!eqlFunc(tmp, tmp2)) {\n return false;\n }\n }\n return tmp == null && tmp2 == null;\n }\n\n get isEmpty(): boolean {\n return this._size == 0;\n }\n\n get size(): number {\n return this._size;\n }\n\n get first(): Nullable<V> {\n return this._firstChild;\n }\n\n get last(): Nullable<V> {\n return this._lastChild;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n let tmp = this._lastChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.prevSibling;\n }\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n let tmp = this._firstChild;\n while (tmp != null) {\n yield tmp;\n tmp = tmp.nextSibling;\n }\n }\n\n add(child: V, before: Nullable<V> = null): this {\n // Ensure that this node is not added anywhere else\n if (child.nextSibling != null || child.prevSibling != null) {\n throw new Error(\"New node already added to a list. Remove it first\");\n }\n child.nextSibling = child.prevSibling = null;\n this._size++;\n if (this._firstChild == null || this._lastChild == null) {\n this._firstChild = this._lastChild = child;\n } else if (before == null) {\n child.prevSibling = this._lastChild;\n child.nextSibling = null;\n this._lastChild.nextSibling = child;\n this._lastChild = child;\n } else if (before == this._firstChild) {\n child.nextSibling = before;\n child.prevSibling = null;\n this._firstChild.prevSibling = child;\n this._firstChild = child;\n } else {\n const prev = before.prevSibling;\n child.nextSibling = before;\n before.prevSibling = child;\n child.prevSibling = prev;\n if (prev != null) {\n prev.nextSibling = child;\n }\n }\n return this;\n }\n\n pushFront(value: V): this {\n return this.add(value, this._firstChild);\n }\n\n pushBack(value: V): this {\n return this.add(value);\n }\n\n /**\n * Removes a child node from this list.\n * It is upto the caller to ensure that this node indeed belongs\n * to this list otherwise deletion of a non belonging node could result\n * in undefined behaviour.\n */\n remove(child: V): this {\n const next = child.nextSibling;\n const prev = child.prevSibling;\n\n if (next == null) {\n this._lastChild = prev;\n if (prev == null) this._firstChild = null;\n } else {\n next.prevSibling = prev;\n }\n\n if (prev == null) {\n this._firstChild = next;\n if (next == null) this._lastChild = null;\n } else {\n prev.nextSibling = next;\n }\n\n this._size--;\n\n child.prevSibling = child.nextSibling = null;\n return this;\n }\n\n popBack(): V {\n if (this._lastChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._lastChild;\n this.remove(out);\n return out;\n }\n\n popFront(): V {\n if (this._firstChild == null) {\n throw new Error(\"No children\");\n }\n const out = this._firstChild;\n this.remove(out);\n return out;\n }\n}\n\n/**\n * A list implementation where the values themselves need to be wrapper in a list node.\n * If values already have sibling node properties they can be direclty used\n * via ValueLists.\n */\nexport class List<V> {\n private container: ValueList<MutableListNode<V>>;\n\n constructor(...values: V[]) {\n this.container = new ValueList<MutableListNode<V>>();\n for (const v of values) this.push(v);\n }\n\n toJSON(): V[] {\n return Array.from(this.values());\n }\n\n forEach(method: (val: V) => boolean | any): number {\n return this.container.forEach((v) => method(v.value));\n }\n\n equals(another: List<V>, eqlFunc: (val1: V, val2: V) => boolean): boolean {\n return this.container.equals(another.container, (a, b) => eqlFunc(a.value, b.value));\n }\n\n find(target: V): Nullable<MutableListNode<V>> {\n for (const v of this.container.values()) {\n if (target == v.value) {\n return v;\n }\n }\n return null;\n }\n\n get isEmpty(): boolean {\n return this.container.isEmpty;\n }\n\n get size(): number {\n return this.container.size;\n }\n\n get first(): Nullable<MutableListNode<V>> {\n return this.container.first;\n }\n\n get last(): Nullable<MutableListNode<V>> {\n return this.container.last;\n }\n\n /**\n * Generator of values in reverse order.\n */\n *reversedValues(): Generator<V> {\n for (const v of this.container.reversedValues()) yield v.value;\n }\n\n /**\n * Generator of values in forward order.\n */\n *values(): Generator<V> {\n for (const v of this.container.values()) yield v.value;\n }\n\n popBack(): V {\n return this.container.popBack().value;\n }\n\n popFront(): V {\n return this.container.popFront().value;\n }\n\n pushFront(value: V): this {\n return this.add(value, this.container.first);\n }\n\n push(value: V): this {\n return this.add(value);\n }\n\n add(child: V, before: Nullable<MutableListNode<V>> = null): this {\n this.container.add(new MutableListNode(child), before);\n return this;\n }\n}\n"]}
|
package/lib/cjs/misc.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getCircularReplacer =
|
|
3
|
+
exports.getCircularReplacer = void 0;
|
|
4
|
+
exports.encodeAs = encodeAs;
|
|
5
|
+
exports.dictGet = dictGet;
|
|
6
|
+
exports.ifDefined = ifDefined;
|
|
7
|
+
exports.stripQuotes = stripQuotes;
|
|
8
|
+
exports.trimmedSplit = trimmedSplit;
|
|
9
|
+
exports.ArrayTimesN = ArrayTimesN;
|
|
10
|
+
exports.firstIndexOf = firstIndexOf;
|
|
4
11
|
function encodeAs(value, alphabet) {
|
|
5
12
|
let out = "";
|
|
6
13
|
const nDig = alphabet.length;
|
|
@@ -11,7 +18,6 @@ function encodeAs(value, alphabet) {
|
|
|
11
18
|
}
|
|
12
19
|
return out;
|
|
13
20
|
}
|
|
14
|
-
exports.encodeAs = encodeAs;
|
|
15
21
|
function dictGet(dict, key, onmissing) {
|
|
16
22
|
if (!(key in dict)) {
|
|
17
23
|
if (typeof onmissing === "function")
|
|
@@ -21,11 +27,9 @@ function dictGet(dict, key, onmissing) {
|
|
|
21
27
|
}
|
|
22
28
|
return dict[key];
|
|
23
29
|
}
|
|
24
|
-
exports.dictGet = dictGet;
|
|
25
30
|
function ifDefined(value, elseVal = null) {
|
|
26
31
|
return typeof value === "undefined" ? elseVal : value;
|
|
27
32
|
}
|
|
28
|
-
exports.ifDefined = ifDefined;
|
|
29
33
|
function stripQuotes(str) {
|
|
30
34
|
str = str.trim();
|
|
31
35
|
if (str.startsWith('"'))
|
|
@@ -34,7 +38,6 @@ function stripQuotes(str) {
|
|
|
34
38
|
str = str.substring(0, str.length - 1);
|
|
35
39
|
return str;
|
|
36
40
|
}
|
|
37
|
-
exports.stripQuotes = stripQuotes;
|
|
38
41
|
function trimmedSplit(value, delimiter) {
|
|
39
42
|
if (value == null)
|
|
40
43
|
return [];
|
|
@@ -43,7 +46,6 @@ function trimmedSplit(value, delimiter) {
|
|
|
43
46
|
.map((v) => v.trim())
|
|
44
47
|
.filter((v) => v.length > 0);
|
|
45
48
|
}
|
|
46
|
-
exports.trimmedSplit = trimmedSplit;
|
|
47
49
|
function ArrayTimesN(count, value) {
|
|
48
50
|
const out = [];
|
|
49
51
|
for (let i = 0; i < count; i++) {
|
|
@@ -51,7 +53,6 @@ function ArrayTimesN(count, value) {
|
|
|
51
53
|
}
|
|
52
54
|
return out;
|
|
53
55
|
}
|
|
54
|
-
exports.ArrayTimesN = ArrayTimesN;
|
|
55
56
|
function firstIndexOf(items, cmpFunc, startIndex = 0, ensure = false) {
|
|
56
57
|
for (let i = startIndex; i < items.length; i++) {
|
|
57
58
|
if (cmpFunc(items[i]))
|
|
@@ -62,7 +63,6 @@ function firstIndexOf(items, cmpFunc, startIndex = 0, ensure = false) {
|
|
|
62
63
|
}
|
|
63
64
|
return -1;
|
|
64
65
|
}
|
|
65
|
-
exports.firstIndexOf = firstIndexOf;
|
|
66
66
|
const getCircularReplacer = () => {
|
|
67
67
|
const seen = new WeakSet();
|
|
68
68
|
return (key, value) => {
|
package/lib/cjs/misc.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/misc.ts"],"names":[],"mappings":";;;AAAA,SAAgB,QAAQ,CAAC,KAAa,EAAE,QAAgB;IACtD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC7B,OAAO,KAAK,GAAG,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"misc.js","sourceRoot":"","sources":["../../src/misc.ts"],"names":[],"mappings":"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","sourcesContent":["export function encodeAs(value: number, alphabet: string): string {\n let out = \"\";\n const nDig = alphabet.length;\n while (value > 0) {\n const digit = value % nDig;\n out = alphabet[digit] + out;\n value = Math.floor(value / nDig);\n }\n return out;\n}\n\nexport function dictGet(dict: any, key: string, onmissing: any | ((key: string) => any)): any {\n if (!(key in dict)) {\n if (typeof onmissing === \"function\") return onmissing(key);\n else return onmissing;\n }\n return dict[key];\n}\n\nexport function ifDefined(value: any, elseVal = null): any {\n return typeof value === \"undefined\" ? elseVal : value;\n}\n\nexport function stripQuotes(str: string): string {\n str = str.trim();\n if (str.startsWith('\"')) str = str.substring(1);\n if (str.endsWith('\"')) str = str.substring(0, str.length - 1);\n return str;\n}\n\nexport function trimmedSplit(value: string | null, delimiter: string): string[] {\n if (value == null) return [];\n return (value || \"\")\n .split(delimiter)\n .map((v) => v.trim())\n .filter((v) => v.length > 0);\n}\n\nexport function ArrayTimesN<T = number>(count: number, value: T): T[] {\n const out: T[] = [];\n for (let i = 0; i < count; i++) {\n out.push(value);\n }\n return out;\n}\n\nexport function firstIndexOf<T>(\n items: ReadonlyArray<T>,\n cmpFunc: (t: T) => boolean,\n startIndex = 0,\n ensure = false,\n): number {\n for (let i = startIndex; i < items.length; i++) {\n if (cmpFunc(items[i])) return i;\n }\n if (ensure) {\n throw new Error(\"Matching item not found\");\n }\n return -1;\n}\n\nexport const getCircularReplacer = () => {\n const seen = new WeakSet();\n return (key: any, value: any) => {\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value)) {\n return;\n }\n seen.add(value);\n }\n return value;\n };\n};\n"]}
|
package/lib/cjs/numberutils.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Frac = exports.Fraction =
|
|
3
|
+
exports.Frac = exports.Fraction = void 0;
|
|
4
|
+
exports.range = range;
|
|
5
|
+
exports.gcdof = gcdof;
|
|
4
6
|
function range(start, end = null, incr = 1) {
|
|
5
7
|
if (end == null) {
|
|
6
8
|
const absStart = Math.abs(start);
|
|
@@ -31,7 +33,6 @@ function range(start, end = null, incr = 1) {
|
|
|
31
33
|
}
|
|
32
34
|
return out;
|
|
33
35
|
}
|
|
34
|
-
exports.range = range;
|
|
35
36
|
function gcdof(x, y) {
|
|
36
37
|
x = Math.abs(x);
|
|
37
38
|
y = Math.abs(y);
|
|
@@ -42,7 +43,6 @@ function gcdof(x, y) {
|
|
|
42
43
|
}
|
|
43
44
|
return x;
|
|
44
45
|
}
|
|
45
|
-
exports.gcdof = gcdof;
|
|
46
46
|
class Fraction {
|
|
47
47
|
constructor(num = 0, den = 1, factorized = false) {
|
|
48
48
|
if (isNaN(num) || isNaN(den)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"numberutils.js","sourceRoot":"","sources":["../../src/numberutils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport function range(start: number, end: Nullable<number> = null, incr: Nullable<number> = 1): number[] {\n if (end == null) {\n const absStart = Math.abs(start);\n const arr = Array.from({ length: absStart });\n if (start >= 0) {\n return arr.map((x, i) => i);\n } else {\n return arr.map((x, i) => i - (absStart - 1));\n }\n }\n const out: number[] = [];\n if (incr == null) {\n incr = 1;\n }\n incr = Math.abs(incr);\n if (start !== end) {\n if (start < end) {\n for (let i = start; i <= end; i += incr) {\n out.push(i);\n }\n } else {\n for (let i = start; i >= end; i -= incr) {\n out.push(i);\n }\n }\n }\n return out;\n}\n\nexport function gcdof(x: number, y: number): number {\n x = Math.abs(x);\n y = Math.abs(y);\n while (y > 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x;\n}\n\nexport class Fraction {\n readonly num: number;\n readonly den: number;\n\n static readonly ZERO = new Fraction();\n static readonly ONE = new Fraction(1, 1);\n static readonly INFINITY = new Fraction(1, 0);\n\n constructor(num = 0, den = 1, factorized = false) {\n if (isNaN(num) || isNaN(den)) {\n throw new Error(`Invalid numerator(${num}) or denminator(${den})`);\n }\n if (factorized) {\n const gcd = gcdof(num, den);\n num /= gcd;\n den /= gcd;\n }\n this.num = num;\n this.den = den;\n }\n\n static parse(val: string, factorized = false): Fraction {\n const parts = val\n .trim()\n .split(\"/\")\n .map((x) => x.trim());\n let num = 1;\n let den = 1;\n if (parts.length == 1) num = parseInt(parts[0]);\n else if (parts.length != 2) {\n throw new Error(\"Invalid fraction string: \" + val);\n } else {\n if (parts[0].length > 0) {\n num = parseInt(parts[0]);\n }\n if (parts[1].length > 0) {\n den = parseInt(parts[1]);\n }\n }\n if (isNaN(num) || isNaN(den)) {\n throw new Error(\"Invalid fraction string: \" + val);\n }\n return new Fraction(num, den, factorized);\n }\n\n get isWhole(): boolean {\n return this.num % this.den == 0;\n }\n\n get isZero(): boolean {\n return this.num == 0;\n }\n\n get isInfinity(): boolean {\n return this.den == 0;\n }\n\n get isOne(): boolean {\n return this.num == this.den;\n }\n\n get ceil(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return 1 + Math.floor(this.num / this.den);\n }\n }\n\n get floor(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return Math.floor(this.num / this.den);\n }\n }\n\n plus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den, factorized);\n }\n\n plusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num + this.den * another, this.den, factorized);\n }\n\n minus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den, factorized);\n }\n\n minusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num - this.den * another, this.den, factorized);\n }\n\n times(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.num, this.den * another.den, factorized);\n }\n\n timesNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num * another, this.den, factorized);\n }\n\n divby(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den, this.den * another.num, factorized);\n }\n\n divbyNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num, this.den * another, factorized);\n }\n\n /**\n * Returns another / this.\n */\n numDivby(another: number, factorized = false): Fraction {\n return new Fraction(this.den * another, this.num, factorized);\n }\n\n /**\n * Returns this % another\n */\n mod(another: Fraction): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divby(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minus(another.timesNum(floorOfD));\n }\n\n /*\n * Returns this % another\n */\n modNum(another: number): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divbyNum(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minusNum(another * floorOfD);\n }\n\n get inverse(): Fraction {\n return new Fraction(this.den, this.num);\n }\n\n get factorized(): Fraction {\n const gcd = gcdof(this.num, this.den);\n return new Fraction(this.num / gcd, this.den / gcd);\n }\n\n equals(another: Fraction): boolean {\n return this.num * another.den == this.den * another.num;\n }\n\n equalsNum(another: number): boolean {\n return this.num == this.den * another;\n }\n\n cmp(another: Fraction): number {\n return this.num * another.den - this.den * another.num;\n }\n\n cmpNum(another: number): number {\n return this.num - this.den * another;\n }\n\n isLT(another: Fraction): boolean {\n return this.cmp(another) < 0;\n }\n\n isLTE(another: Fraction): boolean {\n return this.cmp(another) <= 0;\n }\n\n isLTNum(another: number): boolean {\n return this.cmpNum(another) < 0;\n }\n\n isLTENum(another: number): boolean {\n return this.cmpNum(another) <= 0;\n }\n\n isGT(another: Fraction): boolean {\n return this.cmp(another) > 0;\n }\n\n isGTE(another: Fraction): boolean {\n return this.cmp(another) >= 0;\n }\n\n isGTNum(another: number): boolean {\n return this.cmpNum(another) > 0;\n }\n\n isGTENum(another: number): boolean {\n return this.cmpNum(another) >= 0;\n }\n\n toString(): string {\n return this.num + \"/\" + this.den;\n }\n\n static max(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) > 0 ? f1 : f2;\n }\n\n static min(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) < 0 ? f1 : f2;\n }\n}\n\n// Shortcut helper\nexport const Frac = (a = 0, b = 1, factorized = false): Fraction => new Fraction(a, b, factorized);\n"]}
|
|
1
|
+
{"version":3,"file":"numberutils.js","sourceRoot":"","sources":["../../src/numberutils.ts"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from \"./types\";\n\nexport function range(start: number, end: Nullable<number> = null, incr: Nullable<number> = 1): number[] {\n if (end == null) {\n const absStart = Math.abs(start);\n const arr = Array.from({ length: absStart });\n if (start >= 0) {\n return arr.map((x, i) => i);\n } else {\n return arr.map((x, i) => i - (absStart - 1));\n }\n }\n const out: number[] = [];\n if (incr == null) {\n incr = 1;\n }\n incr = Math.abs(incr);\n if (start !== end) {\n if (start < end) {\n for (let i = start; i <= end; i += incr) {\n out.push(i);\n }\n } else {\n for (let i = start; i >= end; i -= incr) {\n out.push(i);\n }\n }\n }\n return out;\n}\n\nexport function gcdof(x: number, y: number): number {\n x = Math.abs(x);\n y = Math.abs(y);\n while (y > 0) {\n const t = y;\n y = x % y;\n x = t;\n }\n return x;\n}\n\nexport class Fraction {\n readonly num: number;\n readonly den: number;\n\n static readonly ZERO = new Fraction();\n static readonly ONE = new Fraction(1, 1);\n static readonly INFINITY = new Fraction(1, 0);\n\n constructor(num = 0, den = 1, factorized = false) {\n if (isNaN(num) || isNaN(den)) {\n throw new Error(`Invalid numerator(${num}) or denminator(${den})`);\n }\n if (factorized) {\n const gcd = gcdof(num, den);\n num /= gcd;\n den /= gcd;\n }\n this.num = num;\n this.den = den;\n }\n\n static parse(val: string, factorized = false): Fraction {\n const parts = val\n .trim()\n .split(\"/\")\n .map((x) => x.trim());\n let num = 1;\n let den = 1;\n if (parts.length == 1) num = parseInt(parts[0]);\n else if (parts.length != 2) {\n throw new Error(\"Invalid fraction string: \" + val);\n } else {\n if (parts[0].length > 0) {\n num = parseInt(parts[0]);\n }\n if (parts[1].length > 0) {\n den = parseInt(parts[1]);\n }\n }\n if (isNaN(num) || isNaN(den)) {\n throw new Error(\"Invalid fraction string: \" + val);\n }\n return new Fraction(num, den, factorized);\n }\n\n get isWhole(): boolean {\n return this.num % this.den == 0;\n }\n\n get isZero(): boolean {\n return this.num == 0;\n }\n\n get isInfinity(): boolean {\n return this.den == 0;\n }\n\n get isOne(): boolean {\n return this.num == this.den;\n }\n\n get ceil(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return 1 + Math.floor(this.num / this.den);\n }\n }\n\n get floor(): number {\n if (this.num % this.den == 0) {\n return this.num / this.den;\n } else {\n return Math.floor(this.num / this.den);\n }\n }\n\n plus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den + this.den * another.num, this.den * another.den, factorized);\n }\n\n plusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num + this.den * another, this.den, factorized);\n }\n\n minus(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den - this.den * another.num, this.den * another.den, factorized);\n }\n\n minusNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num - this.den * another, this.den, factorized);\n }\n\n times(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.num, this.den * another.den, factorized);\n }\n\n timesNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num * another, this.den, factorized);\n }\n\n divby(another: Fraction, factorized = false): Fraction {\n return new Fraction(this.num * another.den, this.den * another.num, factorized);\n }\n\n divbyNum(another: number, factorized = false): Fraction {\n return new Fraction(this.num, this.den * another, factorized);\n }\n\n /**\n * Returns another / this.\n */\n numDivby(another: number, factorized = false): Fraction {\n return new Fraction(this.den * another, this.num, factorized);\n }\n\n /**\n * Returns this % another\n */\n mod(another: Fraction): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divby(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minus(another.timesNum(floorOfD));\n }\n\n /*\n * Returns this % another\n */\n modNum(another: number): Fraction {\n // a (mod b) = a − b ⌊a / b⌋\n const d = this.divbyNum(another);\n const floorOfD = Math.floor(d.num / d.den);\n return this.minusNum(another * floorOfD);\n }\n\n get inverse(): Fraction {\n return new Fraction(this.den, this.num);\n }\n\n get factorized(): Fraction {\n const gcd = gcdof(this.num, this.den);\n return new Fraction(this.num / gcd, this.den / gcd);\n }\n\n equals(another: Fraction): boolean {\n return this.num * another.den == this.den * another.num;\n }\n\n equalsNum(another: number): boolean {\n return this.num == this.den * another;\n }\n\n cmp(another: Fraction): number {\n return this.num * another.den - this.den * another.num;\n }\n\n cmpNum(another: number): number {\n return this.num - this.den * another;\n }\n\n isLT(another: Fraction): boolean {\n return this.cmp(another) < 0;\n }\n\n isLTE(another: Fraction): boolean {\n return this.cmp(another) <= 0;\n }\n\n isLTNum(another: number): boolean {\n return this.cmpNum(another) < 0;\n }\n\n isLTENum(another: number): boolean {\n return this.cmpNum(another) <= 0;\n }\n\n isGT(another: Fraction): boolean {\n return this.cmp(another) > 0;\n }\n\n isGTE(another: Fraction): boolean {\n return this.cmp(another) >= 0;\n }\n\n isGTNum(another: number): boolean {\n return this.cmpNum(another) > 0;\n }\n\n isGTENum(another: number): boolean {\n return this.cmpNum(another) >= 0;\n }\n\n toString(): string {\n return this.num + \"/\" + this.den;\n }\n\n static max(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) > 0 ? f1 : f2;\n }\n\n static min(f1: Fraction, f2: Fraction): Fraction {\n return f1.cmp(f2) < 0 ? f1 : f2;\n }\n}\n\n// Shortcut helper\nexport const Frac = (a = 0, b = 1, factorized = false): Fraction => new Fraction(a, b, factorized);\n"]}
|
package/lib/cjs/scrolling.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
export declare class ScrollGroup {
|
|
2
|
+
debugLogs: boolean;
|
|
3
|
+
private scrollables;
|
|
4
|
+
private isScrolling;
|
|
5
|
+
private _focussedScrollable;
|
|
6
|
+
constructor(debugLogs?: boolean);
|
|
7
|
+
add(scrollable: Scrollable): void;
|
|
8
|
+
remove(scrollable: Scrollable): void;
|
|
9
|
+
clear(): void;
|
|
10
|
+
detachAtIndex(index: number): Scrollable;
|
|
11
|
+
syncFollowersToLeader(source: Scrollable): void;
|
|
12
|
+
}
|
|
1
13
|
export interface Scrollable {
|
|
2
14
|
scrollOffset: number;
|
|
3
15
|
readonly scrollSize: number;
|
|
@@ -24,26 +36,3 @@ export declare class HTMLElementScrollable implements Scrollable {
|
|
|
24
36
|
onTouchEvent(event: TouchEvent): void;
|
|
25
37
|
onMouseEvent(event: MouseEvent): void;
|
|
26
38
|
}
|
|
27
|
-
export declare class ScrollGroup {
|
|
28
|
-
debugLogs: boolean;
|
|
29
|
-
private scrollables;
|
|
30
|
-
private _focussedScrollable;
|
|
31
|
-
private leadScrollable;
|
|
32
|
-
private lastScrolledAt;
|
|
33
|
-
private lastScrollOffset;
|
|
34
|
-
private scrollTimer;
|
|
35
|
-
private idleThreshold;
|
|
36
|
-
private offsetDeltaThreshold;
|
|
37
|
-
private eventDeltaThreshold;
|
|
38
|
-
constructor(debugLogs?: boolean);
|
|
39
|
-
add(scrollable: Scrollable): void;
|
|
40
|
-
remove(scrollable: Scrollable): void;
|
|
41
|
-
clear(): void;
|
|
42
|
-
detachAtIndex(index: number): Scrollable;
|
|
43
|
-
syncFollowersToLeader(): void;
|
|
44
|
-
set focussedScrollable(scrollable: Scrollable | null);
|
|
45
|
-
onScroll(scrollable: Scrollable, timestamp: number): void;
|
|
46
|
-
setLeadScrollable(scrollable: Scrollable): Scrollable | null;
|
|
47
|
-
onTimer(ts: number): void;
|
|
48
|
-
protected scrollingFinished(ts: number): void;
|
|
49
|
-
}
|
package/lib/cjs/scrolling.js
CHANGED
|
@@ -1,7 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
|
|
3
|
+
exports.HTMLElementScrollable = exports.ScrollGroup = void 0;
|
|
4
|
+
class ScrollGroup {
|
|
5
|
+
constructor(debugLogs = false) {
|
|
6
|
+
this.debugLogs = debugLogs;
|
|
7
|
+
this.scrollables = [];
|
|
8
|
+
this.isScrolling = false;
|
|
9
|
+
this._focussedScrollable = null;
|
|
10
|
+
}
|
|
11
|
+
add(scrollable) {
|
|
12
|
+
const index = this.scrollables.indexOf(scrollable);
|
|
13
|
+
if (index >= 0)
|
|
14
|
+
return;
|
|
15
|
+
scrollable.attach(this);
|
|
16
|
+
this.scrollables.push(scrollable);
|
|
17
|
+
}
|
|
18
|
+
remove(scrollable) {
|
|
19
|
+
const index = this.scrollables.indexOf(scrollable);
|
|
20
|
+
if (index < 0)
|
|
21
|
+
return;
|
|
22
|
+
this.detachAtIndex(index);
|
|
23
|
+
}
|
|
24
|
+
clear() {
|
|
25
|
+
for (let i = this.scrollables.length - 1; i >= 0; i--) {
|
|
26
|
+
this.detachAtIndex(i);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
detachAtIndex(index) {
|
|
30
|
+
const scrollable = this.scrollables[index];
|
|
31
|
+
scrollable.detach();
|
|
32
|
+
this.scrollables.splice(index, 1);
|
|
33
|
+
return scrollable;
|
|
34
|
+
}
|
|
35
|
+
syncFollowersToLeader(source) {
|
|
36
|
+
if (this.isScrolling)
|
|
37
|
+
return;
|
|
38
|
+
this.isScrolling = true;
|
|
39
|
+
const remScroll = Math.max(1, source.scrollSize - source.pageSize);
|
|
40
|
+
const scrollPct = source.scrollOffset / remScroll;
|
|
41
|
+
for (let i = this.scrollables.length - 1; i >= 0; i--) {
|
|
42
|
+
const other = this.scrollables[i];
|
|
43
|
+
if (other != source) {
|
|
44
|
+
other.scrollOffset = scrollPct * (other.scrollSize - other.pageSize);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
setTimeout(() => { this.isScrolling = true; }, 50);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.ScrollGroup = ScrollGroup;
|
|
5
51
|
class HTMLElementScrollable {
|
|
6
52
|
constructor(element, vertical = true) {
|
|
7
53
|
this._scrollGroup = null;
|
|
@@ -72,124 +118,23 @@ class HTMLElementScrollable {
|
|
|
72
118
|
}
|
|
73
119
|
onScrollEvent(event) {
|
|
74
120
|
var _a;
|
|
75
|
-
(_a = this.scrollGroup) === null || _a === void 0 ? void 0 : _a.
|
|
121
|
+
(_a = this.scrollGroup) === null || _a === void 0 ? void 0 : _a.syncFollowersToLeader(this);
|
|
76
122
|
}
|
|
77
123
|
onTouchEvent(event) {
|
|
78
124
|
if (event.type == "touchstart" && this.scrollGroup) {
|
|
79
|
-
this.scrollGroup.focussedScrollable = this;
|
|
80
125
|
}
|
|
81
126
|
}
|
|
82
127
|
onMouseEvent(event) {
|
|
83
128
|
const element = event.target;
|
|
84
129
|
if (this.scrollGroup) {
|
|
85
130
|
if (event.type == "mouseenter") {
|
|
86
|
-
this.scrollGroup.focussedScrollable = this;
|
|
87
131
|
}
|
|
88
132
|
else if (event.type == "mouseleave") {
|
|
89
|
-
this.scrollGroup.focussedScrollable = null;
|
|
90
133
|
}
|
|
91
134
|
else if (event.type == "mousedown") {
|
|
92
|
-
this.scrollGroup.focussedScrollable = this;
|
|
93
135
|
}
|
|
94
136
|
}
|
|
95
137
|
}
|
|
96
138
|
}
|
|
97
139
|
exports.HTMLElementScrollable = HTMLElementScrollable;
|
|
98
|
-
class ScrollGroup {
|
|
99
|
-
constructor(debugLogs = false) {
|
|
100
|
-
this.debugLogs = debugLogs;
|
|
101
|
-
this.scrollables = [];
|
|
102
|
-
this._focussedScrollable = null;
|
|
103
|
-
this.leadScrollable = null;
|
|
104
|
-
this.lastScrolledAt = -1;
|
|
105
|
-
this.lastScrollOffset = 0;
|
|
106
|
-
this.idleThreshold = 300;
|
|
107
|
-
this.offsetDeltaThreshold = 5;
|
|
108
|
-
this.eventDeltaThreshold = 50;
|
|
109
|
-
this.scrollTimer = new timer_1.Timer(500, this.onTimer.bind(this));
|
|
110
|
-
}
|
|
111
|
-
add(scrollable) {
|
|
112
|
-
const index = this.scrollables.indexOf(scrollable);
|
|
113
|
-
if (index >= 0)
|
|
114
|
-
return;
|
|
115
|
-
scrollable.attach(this);
|
|
116
|
-
this.scrollables.push(scrollable);
|
|
117
|
-
}
|
|
118
|
-
remove(scrollable) {
|
|
119
|
-
const index = this.scrollables.indexOf(scrollable);
|
|
120
|
-
if (index < 0)
|
|
121
|
-
return;
|
|
122
|
-
this.detachAtIndex(index);
|
|
123
|
-
}
|
|
124
|
-
clear() {
|
|
125
|
-
for (let i = this.scrollables.length - 1; i >= 0; i--) {
|
|
126
|
-
this.detachAtIndex(i);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
detachAtIndex(index) {
|
|
130
|
-
const scrollable = this.scrollables[index];
|
|
131
|
-
scrollable.detach();
|
|
132
|
-
this.scrollables.splice(index, 1);
|
|
133
|
-
return scrollable;
|
|
134
|
-
}
|
|
135
|
-
syncFollowersToLeader() {
|
|
136
|
-
const scrollable = this.leadScrollable;
|
|
137
|
-
if (scrollable != null) {
|
|
138
|
-
this.lastScrollOffset = scrollable.scrollOffset;
|
|
139
|
-
const remScroll = Math.max(1, scrollable.scrollSize - scrollable.pageSize);
|
|
140
|
-
for (let i = this.scrollables.length - 1; i >= 0; i--) {
|
|
141
|
-
const other = this.scrollables[i];
|
|
142
|
-
const remOther = Math.max(1, other.scrollSize - other.pageSize);
|
|
143
|
-
if (other != scrollable) {
|
|
144
|
-
other.scrollOffset = (scrollable.scrollOffset * remOther) / remScroll;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
set focussedScrollable(scrollable) {
|
|
150
|
-
this._focussedScrollable = scrollable;
|
|
151
|
-
}
|
|
152
|
-
onScroll(scrollable, timestamp) {
|
|
153
|
-
if (this.leadScrollable == null) {
|
|
154
|
-
this.setLeadScrollable(scrollable);
|
|
155
|
-
}
|
|
156
|
-
const leader = this.leadScrollable;
|
|
157
|
-
if (leader != null) {
|
|
158
|
-
const offsetDelta = Math.abs(leader.scrollOffset - this.lastScrollOffset);
|
|
159
|
-
const timeDelta = Math.abs(timestamp - this.lastScrolledAt);
|
|
160
|
-
if (offsetDelta > this.offsetDeltaThreshold || timeDelta > this.eventDeltaThreshold) {
|
|
161
|
-
this.lastScrolledAt = timestamp;
|
|
162
|
-
this.syncFollowersToLeader();
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
setLeadScrollable(scrollable) {
|
|
167
|
-
if (this.leadScrollable == null) {
|
|
168
|
-
this.leadScrollable = scrollable;
|
|
169
|
-
if (this.debugLogs)
|
|
170
|
-
console.log("Scrolling started with: ", scrollable);
|
|
171
|
-
this.scrollTimer.start();
|
|
172
|
-
}
|
|
173
|
-
else {
|
|
174
|
-
throw new Error("This should now happen");
|
|
175
|
-
}
|
|
176
|
-
return this.leadScrollable;
|
|
177
|
-
}
|
|
178
|
-
onTimer(ts) {
|
|
179
|
-
if (this.leadScrollable != null && ts - this.lastScrolledAt > this.idleThreshold) {
|
|
180
|
-
const offsetDelta = Math.abs(this.leadScrollable.scrollOffset - this.lastScrollOffset);
|
|
181
|
-
if (offsetDelta == 0) {
|
|
182
|
-
this.scrollingFinished(ts);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
scrollingFinished(ts) {
|
|
187
|
-
if (this.debugLogs)
|
|
188
|
-
console.log("Scrolling Finished at: ", ts);
|
|
189
|
-
this.syncFollowersToLeader();
|
|
190
|
-
this.leadScrollable = null;
|
|
191
|
-
this.scrollTimer.stop();
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
exports.ScrollGroup = ScrollGroup;
|
|
195
140
|
//# sourceMappingURL=scrolling.js.map
|
package/lib/cjs/scrolling.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scrolling.js","sourceRoot":"","sources":["../../src/scrolling.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timer } from \"./timer\";\n\n/**\n * A scroll group allows one to \"connect\" multiple elements to be\n * scrolled synchronously.\n *\n * A typical usecase would be a div showing lines for a code editor\n * and one that shows a line numbers for a code editor.\n *\n * We could also have recursive relationships where elements in\n * a scroll group are connected to other items outside the scroll\n * group and the would form a super scroll group. An example would\n * two UI components A and B that\n * a scroll group is synchronized\n */\n\ntype EventHandler = (evt: any) => void;\nexport interface Scrollable {\n // Set or get the current scroll offset\n scrollOffset: number;\n\n // Get total scroll size\n readonly scrollSize: number;\n\n // Size of the current \"page\".\n // Our scrollOffset + pageSize is always < scrollSize\n readonly pageSize: number;\n\n // Detaches a scrollable from further use\n attach(scrollGroup: ScrollGroup): void;\n detach(): void;\n}\n\n/**\n * A wrapper for html elements that can be scrolled.\n */\nexport class HTMLElementScrollable implements Scrollable {\n private _scrollGroup: ScrollGroup | null = null;\n readonly element: HTMLElement;\n private vertical = true;\n private onScrollEventListener = this.onScrollEvent.bind(this) as EventListener;\n private onMouseEventListener = this.onMouseEvent.bind(this) as EventListener;\n private onTouchEventListener = this.onTouchEvent.bind(this) as EventListener;\n\n constructor(element: HTMLElement, vertical = true) {\n this.element = element;\n this.vertical = vertical;\n }\n\n attach(scrollGroup: ScrollGroup): void {\n if ((this.element as any).scrollGroup == scrollGroup) {\n return;\n } else if ((this.element as any).scrollGroup) {\n throw new Error(\"Detach element from ScrollGroup first.\");\n }\n (this.element as any).scrollGroup = scrollGroup;\n this._scrollGroup = scrollGroup;\n this.element.addEventListener(\"scroll\", this.onScrollEventListener);\n this.element.addEventListener(\"mousedown\", this.onMouseEventListener);\n this.element.addEventListener(\"mouseenter\", this.onMouseEventListener);\n this.element.addEventListener(\"mouseleave\", this.onMouseEventListener);\n this.element.addEventListener(\"touchstart\", this.onTouchEventListener);\n }\n\n detach(): void {\n (this.element as any).scrollGroup = null;\n this.element.removeEventListener(\"scroll\", this.onScrollEventListener);\n this.element.removeEventListener(\"mousedown\", this.onMouseEventListener);\n this.element.removeEventListener(\"mouseenter\", this.onMouseEventListener);\n this.element.removeEventListener(\"mouseleave\", this.onMouseEventListener);\n this.element.removeEventListener(\"touchstart\", this.onTouchEventListener);\n }\n\n get scrollGroup(): ScrollGroup | null {\n return this._scrollGroup;\n }\n\n // Set or get the current scroll offset\n get scrollOffset(): number {\n if (this.vertical) {\n return this.element.scrollTop;\n } else {\n return this.element.scrollLeft;\n }\n }\n\n set scrollOffset(value: number) {\n if (this.vertical) {\n this.element.scrollTop = value;\n } else {\n this.element.scrollLeft = value;\n }\n }\n\n // Get total scroll size\n get scrollSize(): number {\n if (this.vertical) {\n return this.element.scrollHeight;\n } else {\n return this.element.scrollWidth;\n }\n }\n\n // Size of the current \"page\".\n // Our scrollOffset + pageSize is always < scrollSize\n get pageSize(): number {\n if (this.vertical) {\n return this.element.clientHeight;\n } else {\n return this.element.clientWidth;\n }\n }\n\n onScrollEvent(event: Event): void {\n /**\n * Scroll events will be sent for all elements that are scrolling\n * either programatically or invoked via gestures.\n * It is not possible to know which of these it is and the problem\n * with this is that by handling all events it could result in an\n * infinite loop kicking each other off.\n *\n * So we need a way to be able differentiate scroll events between\n * those that were the \"source\" and those that are \"followers\".\n * We can try a few strategies here:\n *\n * 1. Take the first scroll event's target as the source\n * and kick off a timer to check when scroll events stop. As long\n * as scroll events come from this source we update followers.\n */\n this.scrollGroup?.onScroll(this, event.timeStamp);\n }\n\n onTouchEvent(event: TouchEvent): void {\n // console.log(`Touched Eeent(${event.type}): `, event);\n if (event.type == \"touchstart\" && this.scrollGroup) {\n this.scrollGroup.focussedScrollable = this;\n // this.setLeadScrollable(this.focussedElement);\n }\n }\n\n onMouseEvent(event: MouseEvent): void {\n // console.log(`Mouse Event(${event.type}): `, event);\n const element = event.target;\n if (this.scrollGroup) {\n if (event.type == \"mouseenter\") {\n this.scrollGroup.focussedScrollable = this;\n } else if (event.type == \"mouseleave\") {\n this.scrollGroup.focussedScrollable = null;\n } else if (event.type == \"mousedown\") {\n this.scrollGroup.focussedScrollable = this;\n // this.setLeadScrollable(this.focussedElement);\n }\n }\n }\n}\n\nexport class ScrollGroup {\n private scrollables: Scrollable[] = [];\n private _focussedScrollable: Scrollable | null = null;\n private leadScrollable: Scrollable | null = null;\n private lastScrolledAt = -1;\n private lastScrollOffset = 0;\n private scrollTimer: Timer;\n\n // If there has been no change in scroll offset within this\n // time then we can assume scrolling has completed and this\n // can be used to infer that scrolling has finished.\n private idleThreshold = 300;\n\n // Apply sync to followers if we have a scroll distance of atleast\n // this much or time between last even has crossed the\n // `eventDeltaThreshold`.\n private offsetDeltaThreshold = 5;\n private eventDeltaThreshold = 50;\n\n constructor(public debugLogs = false) {\n this.scrollTimer = new Timer(500, this.onTimer.bind(this));\n }\n\n add(scrollable: Scrollable): void {\n // skip if already exists\n const index = this.scrollables.indexOf(scrollable);\n if (index >= 0) return;\n scrollable.attach(this);\n this.scrollables.push(scrollable);\n }\n\n remove(scrollable: Scrollable): void {\n const index = this.scrollables.indexOf(scrollable);\n if (index < 0) return;\n this.detachAtIndex(index);\n }\n\n clear(): void {\n for (let i = this.scrollables.length - 1; i >= 0; i--) {\n this.detachAtIndex(i);\n }\n }\n\n detachAtIndex(index: number): Scrollable {\n const scrollable = this.scrollables[index];\n scrollable.detach();\n this.scrollables.splice(index, 1);\n return scrollable;\n }\n\n syncFollowersToLeader(): void {\n const scrollable = this.leadScrollable;\n if (scrollable != null) {\n this.lastScrollOffset = scrollable.scrollOffset;\n // console.log(\"Scrolled: \", scrollable.scrollOffset, event);\n\n // set the scroll position of all others\n // TODO - should this happen in this handler itself?\n const remScroll = Math.max(1, scrollable.scrollSize - scrollable.pageSize);\n for (let i = this.scrollables.length - 1; i >= 0; i--) {\n const other = this.scrollables[i];\n const remOther = Math.max(1, other.scrollSize - other.pageSize);\n /*\n console.log(\"Scrollable: \", i, other);\n console.log(\n \"scrollOffset, scrollSize, pageSize: \",\n other.scrollOffset,\n other.scrollSize,\n other.pageSize,\n remOther,\n );\n */\n if (other != scrollable) {\n other.scrollOffset = (scrollable.scrollOffset * remOther) / remScroll;\n }\n }\n }\n }\n\n set focussedScrollable(scrollable: Scrollable | null) {\n this._focussedScrollable = scrollable;\n }\n\n onScroll(scrollable: Scrollable, timestamp: number): void {\n if (this.leadScrollable == null) {\n this.setLeadScrollable(scrollable);\n }\n const leader = this.leadScrollable;\n if (leader != null) {\n // update followers\n const offsetDelta = Math.abs(leader.scrollOffset - this.lastScrollOffset);\n const timeDelta = Math.abs(timestamp - this.lastScrolledAt);\n if (offsetDelta > this.offsetDeltaThreshold || timeDelta > this.eventDeltaThreshold) {\n this.lastScrolledAt = timestamp;\n this.syncFollowersToLeader();\n }\n }\n }\n\n /**\n * Sets the active scrollable to the focussed element.\n */\n public setLeadScrollable(scrollable: Scrollable): Scrollable | null {\n if (this.leadScrollable == null) {\n // scrolling has not begun yet so set it as the \"root\" scroller\n this.leadScrollable = scrollable;\n if (this.debugLogs) console.log(\"Scrolling started with: \", scrollable);\n this.scrollTimer.start();\n } else {\n // What if there was an already active scrollable?\n // This can happen if:\n throw new Error(\"This should now happen\");\n }\n return this.leadScrollable;\n }\n\n onTimer(ts: number): void {\n // Called with our timer\n if (this.leadScrollable != null && ts - this.lastScrolledAt > this.idleThreshold) {\n const offsetDelta = Math.abs(this.leadScrollable.scrollOffset - this.lastScrollOffset);\n if (offsetDelta == 0) {\n // No change in delta within a time window\n this.scrollingFinished(ts);\n }\n }\n }\n\n protected scrollingFinished(ts: number): void {\n if (this.debugLogs) console.log(\"Scrolling Finished at: \", ts);\n // TODO - See if this can have a jerking effect\n this.syncFollowersToLeader();\n this.leadScrollable = null;\n this.scrollTimer.stop();\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"scrolling.js","sourceRoot":"","sources":["../../src/scrolling.ts"],"names":[],"mappings":"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","sourcesContent":["import { Timer } from \"./timer\";\n\n/**\n * A scroll group allows one to \"connect\" multiple elements to be\n * scrolled synchronously.\n *\n * A typical usecase would be a div showing lines for a code editor\n * and one that shows a line numbers for a code editor.\n *\n * We could also have recursive relationships where elements in\n * a scroll group are connected to other items outside the scroll\n * group and the would form a super scroll group. An example would\n * two UI components A and B that\n * a scroll group is synchronized\n */\n\nexport class ScrollGroup {\n private scrollables: Scrollable[] = [];\n private isScrolling = false;\n private _focussedScrollable: Scrollable | null = null;\n\n constructor(public debugLogs = false) {\n }\n\n add(scrollable: Scrollable): void {\n // skip if already exists\n const index = this.scrollables.indexOf(scrollable);\n if (index >= 0) return;\n scrollable.attach(this);\n this.scrollables.push(scrollable);\n }\n\n remove(scrollable: Scrollable): void {\n const index = this.scrollables.indexOf(scrollable);\n if (index < 0) return;\n this.detachAtIndex(index);\n }\n\n clear(): void {\n for (let i = this.scrollables.length - 1; i >= 0; i--) {\n this.detachAtIndex(i);\n }\n }\n\n detachAtIndex(index: number): Scrollable {\n const scrollable = this.scrollables[index];\n scrollable.detach();\n this.scrollables.splice(index, 1);\n return scrollable;\n }\n\n syncFollowersToLeader(source: Scrollable): void {\n if (this.isScrolling) return;\n this.isScrolling = true;\n\n const remScroll = Math.max(1, source.scrollSize - source.pageSize);\n const scrollPct = source.scrollOffset / remScroll;\n for (let i = this.scrollables.length - 1; i >= 0; i--) {\n const other = this.scrollables[i];\n if (other != source) {\n // const remOther = Math.max(1, other.scrollSize - other.pageSize);\n other.scrollOffset = scrollPct * (other.scrollSize - other.pageSize)\n }\n }\n\n setTimeout(() => { this.isScrolling = true; }, 50);\n }\n}\n\nexport interface Scrollable {\n // Set or get the current scroll offset\n scrollOffset: number;\n\n // Get total scroll size\n readonly scrollSize: number;\n\n // Size of the current \"page\".\n // Our scrollOffset + pageSize is always < scrollSize\n readonly pageSize: number;\n\n // Detaches a scrollable from further use\n attach(scrollGroup: ScrollGroup): void;\n detach(): void;\n}\n\n/**\n * A wrapper for html elements that can be scrolled.\n */\nexport class HTMLElementScrollable implements Scrollable {\n private _scrollGroup: ScrollGroup | null = null;\n readonly element: HTMLElement;\n private vertical = true;\n private onScrollEventListener = this.onScrollEvent.bind(this) as EventListener;\n private onMouseEventListener = this.onMouseEvent.bind(this) as EventListener;\n private onTouchEventListener = this.onTouchEvent.bind(this) as EventListener;\n\n constructor(element: HTMLElement, vertical = true) {\n this.element = element;\n this.vertical = vertical;\n }\n\n attach(scrollGroup: ScrollGroup): void {\n if ((this.element as any).scrollGroup == scrollGroup) {\n return;\n } else if ((this.element as any).scrollGroup) {\n throw new Error(\"Detach element from ScrollGroup first.\");\n }\n (this.element as any).scrollGroup = scrollGroup;\n this._scrollGroup = scrollGroup;\n this.element.addEventListener(\"scroll\", this.onScrollEventListener);\n this.element.addEventListener(\"mousedown\", this.onMouseEventListener);\n this.element.addEventListener(\"mouseenter\", this.onMouseEventListener);\n this.element.addEventListener(\"mouseleave\", this.onMouseEventListener);\n this.element.addEventListener(\"touchstart\", this.onTouchEventListener);\n }\n\n detach(): void {\n (this.element as any).scrollGroup = null;\n this.element.removeEventListener(\"scroll\", this.onScrollEventListener);\n this.element.removeEventListener(\"mousedown\", this.onMouseEventListener);\n this.element.removeEventListener(\"mouseenter\", this.onMouseEventListener);\n this.element.removeEventListener(\"mouseleave\", this.onMouseEventListener);\n this.element.removeEventListener(\"touchstart\", this.onTouchEventListener);\n }\n\n get scrollGroup(): ScrollGroup | null {\n return this._scrollGroup;\n }\n\n // Set or get the current scroll offset\n get scrollOffset(): number {\n if (this.vertical) {\n return this.element.scrollTop;\n } else {\n return this.element.scrollLeft;\n }\n }\n\n set scrollOffset(value: number) {\n if (this.vertical) {\n this.element.scrollTop = value;\n } else {\n this.element.scrollLeft = value;\n }\n }\n\n // Get total scroll size\n get scrollSize(): number {\n if (this.vertical) {\n return this.element.scrollHeight;\n } else {\n return this.element.scrollWidth;\n }\n }\n\n // Size of the current \"page\".\n // Our scrollOffset + pageSize is always < scrollSize\n get pageSize(): number {\n if (this.vertical) {\n return this.element.clientHeight;\n } else {\n return this.element.clientWidth;\n }\n }\n\n onScrollEvent(event: Event): void {\n /**\n * Scroll events will be sent for all elements that are scrolling\n * either programatically or invoked via gestures.\n * It is not possible to know which of these it is and the problem\n * with this is that by handling all events it could result in an\n * infinite loop kicking each other off.\n *\n * So we need a way to be able differentiate scroll events between\n * those that were the \"source\" and those that are \"followers\".\n * We can try a few strategies here:\n *\n * 1. Take the first scroll event's target as the source\n * and kick off a timer to check when scroll events stop. As long\n * as scroll events come from this source we update followers.\n */\n this.scrollGroup?.syncFollowersToLeader(this);\n }\n\n onTouchEvent(event: TouchEvent): void {\n // console.log(`Touched Eeent(${event.type}): `, event);\n if (event.type == \"touchstart\" && this.scrollGroup) {\n // this.scrollGroup.focussedScrollable = this;\n // this.setLeadScrollable(this.focussedElement);\n }\n }\n\n onMouseEvent(event: MouseEvent): void {\n // console.log(`Mouse Event(${event.type}): `, event);\n const element = event.target;\n if (this.scrollGroup) {\n if (event.type == \"mouseenter\") {\n // this.scrollGroup.focussedScrollable = this;\n } else if (event.type == \"mouseleave\") {\n // this.scrollGroup.focussedScrollable = null;\n } else if (event.type == \"mousedown\") {\n // this.scrollGroup.focussedScrollable = this;\n // this.setLeadScrollable(this.focussedElement);\n }\n }\n }\n}\n"]}
|
package/lib/cjs/streams.js
CHANGED
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.streamArray = streamArray;
|
|
4
|
+
exports.streamDict = streamDict;
|
|
5
|
+
exports.mapStream = mapStream;
|
|
6
|
+
exports.filterStream = filterStream;
|
|
7
|
+
exports.collectStream = collectStream;
|
|
4
8
|
function* streamArray(arr) {
|
|
5
9
|
for (let i = 0; i < arr.length; i++) {
|
|
6
10
|
yield [i, arr[i]];
|
|
7
11
|
}
|
|
8
12
|
}
|
|
9
|
-
exports.streamArray = streamArray;
|
|
10
13
|
function* streamDict(dict) {
|
|
11
14
|
for (const key in dict) {
|
|
12
15
|
yield [key, dict[key]];
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
|
-
exports.streamDict = streamDict;
|
|
16
18
|
function* mapStream(stream, mapper) {
|
|
17
19
|
let i = 0;
|
|
18
20
|
for (let next = stream.next(); !next.done; next = stream.next()) {
|
|
@@ -20,7 +22,6 @@ function* mapStream(stream, mapper) {
|
|
|
20
22
|
i++;
|
|
21
23
|
}
|
|
22
24
|
}
|
|
23
|
-
exports.mapStream = mapStream;
|
|
24
25
|
function* filterStream(stream, filterFunc) {
|
|
25
26
|
let i = 0;
|
|
26
27
|
for (let next = stream.next(); !next.done; next = stream.next()) {
|
|
@@ -35,7 +36,6 @@ function* filterStream(stream, filterFunc) {
|
|
|
35
36
|
i++;
|
|
36
37
|
}
|
|
37
38
|
}
|
|
38
|
-
exports.filterStream = filterStream;
|
|
39
39
|
function collectStream(stream, collector, collection) {
|
|
40
40
|
let i = 0;
|
|
41
41
|
for (let next = stream.next(); !next.done; next = stream.next()) {
|
|
@@ -44,5 +44,4 @@ function collectStream(stream, collector, collection) {
|
|
|
44
44
|
}
|
|
45
45
|
return collection;
|
|
46
46
|
}
|
|
47
|
-
exports.collectStream = collectStream;
|
|
48
47
|
//# sourceMappingURL=streams.js.map
|
package/lib/cjs/streams.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../../src/streams.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"streams.js","sourceRoot":"","sources":["../../src/streams.ts"],"names":[],"mappings":";;AAAA,kCAIC;AAED,gCAIC;AAED,8BAMC;AAED,oCAYC;AAED,sCAWC;AA7CD,QAAe,CAAC,CAAC,WAAW,CAAI,GAAqB;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAM,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED,QAAe,CAAC,CAAC,UAAU,CAA+B,IAAS;IACjE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,CAAC,GAAQ,EAAE,IAAI,CAAC,GAAG,CAAM,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED,QAAe,CAAC,CAAC,SAAS,CAAO,MAAoB,EAAE,MAAmC;IACxF,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAC5B,CAAC,EAAE,CAAC;IACN,CAAC;AACH,CAAC;AAED,QAAe,CAAC,CAAC,YAAY,CAAI,MAAoB,EAAE,UAA8C;IACnG,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,CAAC,KAAK,CAAC;YACnB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,KAAK,CAAC;QACnB,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAC3B,MAAoB,EACpB,SAA4C,EAC5C,UAAa;IAEb,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QAChE,UAAU,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC;QAClD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC","sourcesContent":["export function* streamArray<V>(arr: ReadonlyArray<V>): Generator<[number, V]> {\n for (let i = 0; i < arr.length; i++) {\n yield [i, arr[i] as V];\n }\n}\n\nexport function* streamDict<K extends string | number, V>(dict: any): Generator<[K, V]> {\n for (const key in dict) {\n yield [key as K, dict[key] as V];\n }\n}\n\nexport function* mapStream<X, Y>(stream: Generator<X>, mapper: (x: X, index?: number) => Y): Generator<Y> {\n let i = 0;\n for (let next = stream.next(); !next.done; next = stream.next()) {\n yield mapper(next.value, i);\n i++;\n }\n}\n\nexport function* filterStream<X>(stream: Generator<X>, filterFunc?: (x: X, index?: number) => boolean): Generator<X> {\n let i = 0;\n for (let next = stream.next(); !next.done; next = stream.next()) {\n if (filterFunc) {\n if (filterFunc(next.value, i)) {\n yield next.value;\n }\n } else if (next.value) {\n yield next.value;\n }\n i++;\n }\n}\n\nexport function collectStream<X, Y>(\n stream: Generator<X>,\n collector: (x: X, y: Y, index?: number) => Y,\n collection: Y,\n): Y {\n let i = 0;\n for (let next = stream.next(); !next.done; next = stream.next()) {\n collection = collector(next.value, collection, i);\n i++;\n }\n return collection;\n}\n"]}
|
package/lib/cjs/timer.d.ts
CHANGED
package/lib/cjs/timer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timer.js","sourceRoot":"","sources":["../../src/timer.ts"],"names":[],"mappings":";;;AAEA,MAAa,KAAK;IAMhB,YAAY,eAAuB,EAAE,QAAkB;QAL/C,oBAAe,GAAG,IAAI,CAAC;QACvB,kBAAa,GAAG,CAAC,CAAC;QAClB,eAAU,GAAkB,IAAI,CAAC;QAIvC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE;
|
|
1
|
+
{"version":3,"file":"timer.js","sourceRoot":"","sources":["../../src/timer.ts"],"names":[],"mappings":";;;AAEA,MAAa,KAAK;IAMhB,YAAY,eAAuB,EAAE,QAAkB;QAL/C,oBAAe,GAAG,IAAI,CAAC;QACvB,kBAAa,GAAG,CAAC,CAAC;QAClB,eAAU,GAAkB,IAAI,CAAC;QAIvC,IAAI,CAAC,eAAe,GAAG,eAAe,CAAC;QACvC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YAC5B,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACzB,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAES,aAAa;QACrB,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;YAC5B,oBAAoB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,qBAAqB,CAAC,CAAC,SAAS,EAAE,EAAE;YACpD,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;gBAC5B,IAAI,SAAS,GAAG,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;oBAC3D,IAAI,CAAC;wBACH,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;oBAC3B,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;wBAC/C,KAAK,CAAC,4BAA4B,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;wBAClD,OAAO;oBACT,CAAC;oBACD,IAAI,CAAC,aAAa,GAAG,SAAS,CAAC;gBACjC,CAAC;gBACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;gBACvB,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AA3CD,sBA2CC","sourcesContent":["type StepFunc = (ts: number) => void;\n\nexport class Timer {\n private refreshInterval = 1000;\n private lastRefreshAt = 0;\n private updateLoop: number | null = null;\n stepFunc: StepFunc;\n\n constructor(refreshInterval: number, stepFunc: StepFunc) {\n this.refreshInterval = refreshInterval;\n this.stepFunc = stepFunc;\n }\n\n stop(): void {\n if (this.updateLoop != null) {\n cancelAnimationFrame(this.updateLoop);\n this.updateLoop = null;\n }\n }\n\n start(): void {\n this.kickOffUpdate();\n }\n\n protected kickOffUpdate(): void {\n if (this.updateLoop != null) {\n cancelAnimationFrame(this.updateLoop);\n }\n this.updateLoop = requestAnimationFrame((timestamp) => {\n if (this.updateLoop != null) {\n if (timestamp - this.lastRefreshAt >= this.refreshInterval) {\n try {\n this.stepFunc(timestamp);\n } catch (err: any) {\n console.log(\"Error from Timer Handler: \", err);\n alert(\"Error from Timer Handler: \" + err.message);\n return;\n }\n this.lastRefreshAt = timestamp;\n }\n this.updateLoop = null;\n this.kickOffUpdate();\n }\n });\n }\n}\n"]}
|