@cgtk/std 0.0.182
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/array.d.ts +12 -0
- package/array.js +19 -0
- package/assign.d.ts +8 -0
- package/assign.js +26 -0
- package/async.d.ts +5 -0
- package/async.js +27 -0
- package/basen.d.ts +12 -0
- package/basen.js +31 -0
- package/buffer.d.ts +14 -0
- package/buffer.js +54 -0
- package/checks.d.ts +26 -0
- package/checks.js +37 -0
- package/constants.d.ts +5 -0
- package/constants.js +1 -0
- package/dom.d.ts +39 -0
- package/dom.js +31 -0
- package/fn.d.ts +29 -0
- package/fn.js +56 -0
- package/http.d.ts +9 -0
- package/http.js +32 -0
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/iterable.d.ts +41 -0
- package/iterable.js +142 -0
- package/json.d.ts +1 -0
- package/json.js +1 -0
- package/map.d.ts +13 -0
- package/map.js +36 -0
- package/math.d.ts +31 -0
- package/math.js +39 -0
- package/number.d.ts +2 -0
- package/number.js +5 -0
- package/object.d.ts +13 -0
- package/object.js +11 -0
- package/package.json +44 -0
- package/progress.d.ts +6 -0
- package/progress.js +1 -0
- package/schedule.d.ts +8 -0
- package/schedule.js +44 -0
- package/signal.d.ts +19 -0
- package/signal.js +25 -0
- package/stream.d.ts +6 -0
- package/stream.js +26 -0
- package/string.d.ts +5 -0
- package/string.js +22 -0
- package/struct.d.ts +25 -0
- package/struct.js +58 -0
- package/tree.d.ts +20 -0
- package/tree.js +33 -0
- package/treemap.d.ts +13 -0
- package/treemap.js +68 -0
- package/typedarray.d.ts +23 -0
- package/typedarray.js +44 -0
- package/types.d.ts +42 -0
- package/types.js +1 -0
- package/utils.d.ts +4 -0
- package/utils.js +30 -0
- package/weak.d.ts +2 -0
- package/weak.js +5 -0
package/iterable.js
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
import { pipe, comp, scan, apply, noop, identity, constantly } from "./fn.js";
|
2
|
+
import { set } from "./map.js";
|
3
|
+
export const repeat = n => function* (x) { for (let i = 0; i < n; i++)
|
4
|
+
yield x; };
|
5
|
+
export const just = function* (x) { yield x; };
|
6
|
+
export const enumerate = (n = 0) => x => [n++, x];
|
7
|
+
export function* empty() { }
|
8
|
+
;
|
9
|
+
export function* concat(...xxs) { for (const xs of xxs)
|
10
|
+
yield* xs; }
|
11
|
+
;
|
12
|
+
export const toArray = (xs) => xs.toArray();
|
13
|
+
export const map = (f) => (xs) => xs.map(f);
|
14
|
+
export const filter = (f) => (xs) => xs.filter(f);
|
15
|
+
export const drop = (n) => (xs) => xs.drop(n);
|
16
|
+
export const flatMap = (f) => (xs) => xs.flatMap(f);
|
17
|
+
export const forEach = (f = noop) => (xs) => xs.forEach(f);
|
18
|
+
export const some = (f) => (xs) => xs.some(f);
|
19
|
+
export const every = (f) => (xs) => xs.every(f);
|
20
|
+
export const find = (f) => (xs) => xs.find(f);
|
21
|
+
export const flat = (xs) => xs.flatMap(identity);
|
22
|
+
export const prepend = (ys) => (xs) => concat(ys, xs);
|
23
|
+
export const append = (ys) => (xs) => concat(xs, ys);
|
24
|
+
export const first = (xs) => xs.find(constantly(true));
|
25
|
+
export const reduce = (f, a) => (xs) => xs.reduce(f, a);
|
26
|
+
export const traverse = (children, f) => (x) => (f(x), forEach(traverse(children, f))(Iterator.from(children(x))));
|
27
|
+
export const take = n => function* (xs) {
|
28
|
+
for (let i = 0; i < n; i++) {
|
29
|
+
const { done, value } = xs.next();
|
30
|
+
if (done)
|
31
|
+
break;
|
32
|
+
yield value;
|
33
|
+
}
|
34
|
+
};
|
35
|
+
export function* arange(a, b = Number.NaN, s = 1) {
|
36
|
+
if (Number.isNaN(b))
|
37
|
+
b = a, a = 0;
|
38
|
+
for (let i = a; i < b; i += s)
|
39
|
+
yield i;
|
40
|
+
}
|
41
|
+
export const linspace = (a, b, n) => arange(a, b + 1e-6, (b - a) / (n - 1));
|
42
|
+
export const steps = (a, b, s = 1, o = 0, eps = 1e-8) => {
|
43
|
+
const start = Math.floor((a - o + s - eps) / s) * s + o;
|
44
|
+
const end = Math.floor((b - o) / s) * s + o;
|
45
|
+
return arange(start, end + s - eps, s);
|
46
|
+
};
|
47
|
+
export const strided = (n, s) => function* (xs) {
|
48
|
+
const cur = [];
|
49
|
+
for (const x of xs) {
|
50
|
+
cur.push(x);
|
51
|
+
if (cur.length == n) {
|
52
|
+
yield cur;
|
53
|
+
for (let i = 0; i < s; i++)
|
54
|
+
cur.shift();
|
55
|
+
}
|
56
|
+
}
|
57
|
+
};
|
58
|
+
export const stopAt = (p) => function* (xs) {
|
59
|
+
let x = xs.next();
|
60
|
+
while (!x.done) {
|
61
|
+
yield x.value;
|
62
|
+
if (p(x.value))
|
63
|
+
return;
|
64
|
+
x = xs.next();
|
65
|
+
}
|
66
|
+
};
|
67
|
+
export const until = (p) => function* (xs) {
|
68
|
+
if (p())
|
69
|
+
return;
|
70
|
+
let x = xs.next();
|
71
|
+
while (!x.done) {
|
72
|
+
yield x.value;
|
73
|
+
if (p())
|
74
|
+
return;
|
75
|
+
x = xs.next();
|
76
|
+
}
|
77
|
+
};
|
78
|
+
export function* zip(...xs) {
|
79
|
+
let val = xs.map(x => x.next());
|
80
|
+
while (val.every(x => !x.done)) {
|
81
|
+
yield val.map(x => x.value);
|
82
|
+
val = xs.map(x => x.next());
|
83
|
+
}
|
84
|
+
}
|
85
|
+
;
|
86
|
+
export const iterA = async function* (xs) {
|
87
|
+
for await (const x of xs)
|
88
|
+
yield x;
|
89
|
+
};
|
90
|
+
export const forEachA = (f = noop) => async (xs) => {
|
91
|
+
for await (const x of xs)
|
92
|
+
f(x);
|
93
|
+
};
|
94
|
+
export const mapA = f => async function* (xs) {
|
95
|
+
let x = await xs.next();
|
96
|
+
while (!x.done)
|
97
|
+
yield f(x.value), x = await xs.next();
|
98
|
+
};
|
99
|
+
export const flatMapA = (f) => async function* (xs) {
|
100
|
+
let x = await xs.next();
|
101
|
+
while (!x.done) {
|
102
|
+
yield* f(x.value);
|
103
|
+
x = await xs.next();
|
104
|
+
}
|
105
|
+
};
|
106
|
+
export const filterA = f => async function* (xs) {
|
107
|
+
let x = await xs.next();
|
108
|
+
while (!x.done) {
|
109
|
+
if (f(x.value))
|
110
|
+
yield x.value;
|
111
|
+
x = await xs.next();
|
112
|
+
}
|
113
|
+
};
|
114
|
+
export const untilA = (p) => async function* (xs) {
|
115
|
+
if (p())
|
116
|
+
return;
|
117
|
+
let x = await xs.next();
|
118
|
+
while (!x.done) {
|
119
|
+
yield x.value;
|
120
|
+
if (p())
|
121
|
+
return;
|
122
|
+
x = await xs.next();
|
123
|
+
}
|
124
|
+
};
|
125
|
+
export const reduceA = (f, a) => async (xs) => {
|
126
|
+
const g = scan(f)(a);
|
127
|
+
await forEachA()(mapA((x) => a = g(x))(xs));
|
128
|
+
return a;
|
129
|
+
};
|
130
|
+
export const race = (n) => async function* (xs) {
|
131
|
+
const it = pipe(xs, map(enumerate()), map(([i, x]) => [i, x.then(y => [i, y])]));
|
132
|
+
const accum = reduce((set), new Map());
|
133
|
+
const tasks = pipe(it, (take(n)), accum);
|
134
|
+
const next = comp((take(1)), accum);
|
135
|
+
while (tasks.size > 0) {
|
136
|
+
const [i, x] = await Promise.race(tasks.values());
|
137
|
+
tasks.delete(i);
|
138
|
+
yield x;
|
139
|
+
next(it);
|
140
|
+
}
|
141
|
+
};
|
142
|
+
export const zmap = (f) => (...xs) => forEach(apply(f))(zip(...xs));
|
package/json.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export declare const fromBytes: (data: Uint8Array) => any;
|
package/json.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export const fromBytes = (data) => JSON.parse(new TextDecoder("utf-8").decode(data));
|
package/map.d.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import type { Fn, FnV, Optional } from "./types.js";
|
2
|
+
export declare const map: <T, V, K = any>({ create, update, remove }: {
|
3
|
+
create: FnV<[T, K, Map<K, V>], V>;
|
4
|
+
update: FnV<[V, T, K, Map<K, V>], V>;
|
5
|
+
remove?: FnV<[V, K, Map<K, V>]>;
|
6
|
+
}) => (dst?: Map<K, V>) => (src: Map<K, T>) => Map<K, V>;
|
7
|
+
export declare const mapAlloc: <T, S, K = any>(f: FnV<[T, S]>, alloc: Fn<void, T>, remove?: FnV<[T, K, Map<K, T>]>) => (dst?: Map<K, T>) => (src: Map<K, S>) => Map<K, T>;
|
8
|
+
export declare const set: <K, V>(m: Map<K, V>, [i, x]: [K, V]) => Map<K, V>;
|
9
|
+
export declare const get: <K, V>(m: Map<K, V>, k: K, d: V) => V;
|
10
|
+
export declare const update: <K, V>(m: Map<K, V>, k: K, f: FnV<[V | undefined, K, Map<K, V>], V>) => Map<K, V>;
|
11
|
+
export declare const first: <K, V>(m: Map<K, V>) => Optional<V>;
|
12
|
+
export declare const shift: <K, V>(m: Map<K, V>) => Optional<[K, V]>;
|
13
|
+
export declare const reduce: <K, V, T>(m: Map<K, V>, f: FnV<[T, V, K, Map<K, V>], T>, a: T) => T;
|
package/map.js
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
import { isDefined } from "./checks.js";
|
2
|
+
import * as I from "./iterable.js";
|
3
|
+
export const map = ({ create, update, remove }) => (dst = new Map()) => (src) => {
|
4
|
+
for (const k of dst.keys())
|
5
|
+
if (!src.has(k)) {
|
6
|
+
remove && remove(dst.get(k), k, dst);
|
7
|
+
dst.delete(k);
|
8
|
+
}
|
9
|
+
src.forEach((v, k) => {
|
10
|
+
if (!dst.has(k))
|
11
|
+
dst.set(k, create(v, k, dst));
|
12
|
+
else
|
13
|
+
dst.set(k, update(dst.get(k), v, k, dst));
|
14
|
+
});
|
15
|
+
return dst;
|
16
|
+
};
|
17
|
+
export const mapAlloc = (f, alloc, remove) => map({ create: e => f(alloc(), e), update: f, remove });
|
18
|
+
export const set = (m, [i, x]) => (m.set(i, x), m);
|
19
|
+
export const get = (m, k, d) => m.has(k) ? m.get(k) : d;
|
20
|
+
export const update = (m, k, f) => set(m, [k, f(m.get(k), k, m)]);
|
21
|
+
export const first = (m) => {
|
22
|
+
const k = I.first(m.keys());
|
23
|
+
if (isDefined(k))
|
24
|
+
return m.get(k);
|
25
|
+
return undefined;
|
26
|
+
};
|
27
|
+
export const shift = (m) => {
|
28
|
+
const k = I.first(m.keys());
|
29
|
+
if (isDefined(k)) {
|
30
|
+
const v = m.get(k);
|
31
|
+
m.delete(k);
|
32
|
+
return [k, v];
|
33
|
+
}
|
34
|
+
return undefined;
|
35
|
+
};
|
36
|
+
export const reduce = (m, f, a) => (m.forEach((v, k) => a = f(a, v, k, m)), a);
|
package/math.d.ts
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
export declare const PI: number;
|
2
|
+
export declare const TAU: number;
|
3
|
+
export declare const HALF_PI: number;
|
4
|
+
export declare const THIRD_PI: number;
|
5
|
+
export declare const QUARTER_PI: number;
|
6
|
+
export declare const SIXTH_PI: number;
|
7
|
+
export declare const SQRT2: number;
|
8
|
+
export declare const GOLDEN: number;
|
9
|
+
export declare const FOUR_OVER_PI: number;
|
10
|
+
export declare const INV_PI: number;
|
11
|
+
export declare const INV_TAU: number;
|
12
|
+
export declare const INV_HALF_PI: number;
|
13
|
+
export declare const EPS: number;
|
14
|
+
export declare const radians: (x: number) => number;
|
15
|
+
export declare const degrees: (x: number) => number;
|
16
|
+
export declare const safeSqrt: (x: number) => number;
|
17
|
+
export declare const lerp: (a: number, b: number, t: number) => number;
|
18
|
+
export declare const clamp: (a: number, b: number, x: number) => number;
|
19
|
+
export declare const saturate: (x: number) => number;
|
20
|
+
export declare const norm: (a: number, b: number, x: number) => number;
|
21
|
+
export declare const fit: (a: number, b: number, c: number, d: number, x: number) => number;
|
22
|
+
export declare const efit: (a: number, b: number, c: number, d: number, x: number) => number;
|
23
|
+
export declare const fit01: (a: number, b: number, x: number) => number;
|
24
|
+
export declare const ewmabc: (beta?: number, t?: number) => (x: number) => number;
|
25
|
+
export declare const sinc: (x: number) => number;
|
26
|
+
export declare const nextpow2: (x: number) => number;
|
27
|
+
export declare const mod: (x: number, m: number) => number;
|
28
|
+
export declare const logn: (n: number, x: number) => number;
|
29
|
+
export declare const floordiv: (x: number, b: number) => number;
|
30
|
+
export declare const zoom: (x: number, s: number, p: number) => number;
|
31
|
+
export declare const align: (x: number, b: number) => number;
|
package/math.js
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
export const PI = Math.PI;
|
2
|
+
export const TAU = PI * 2;
|
3
|
+
export const HALF_PI = PI / 2;
|
4
|
+
export const THIRD_PI = PI / 3;
|
5
|
+
export const QUARTER_PI = PI / 4;
|
6
|
+
export const SIXTH_PI = PI / 6;
|
7
|
+
export const SQRT2 = Math.sqrt(2);
|
8
|
+
export const GOLDEN = (1 + 5 ** .5) * .5;
|
9
|
+
export const FOUR_OVER_PI = 4 / Math.PI;
|
10
|
+
export const INV_PI = 1 / PI;
|
11
|
+
export const INV_TAU = 1 / TAU;
|
12
|
+
export const INV_HALF_PI = 1 / HALF_PI;
|
13
|
+
export const EPS = Number.EPSILON;
|
14
|
+
const DEG2RAD = PI / 180, RAD2DEG = 180 / PI;
|
15
|
+
export const radians = (x) => x * DEG2RAD;
|
16
|
+
export const degrees = (x) => x * RAD2DEG;
|
17
|
+
export const safeSqrt = (x) => Math.sqrt(Math.max(x, 0));
|
18
|
+
export const lerp = (a, b, t) => a * (1 - t) + b * t;
|
19
|
+
export const clamp = (a, b, x) => Math.max(a, Math.min(b, x));
|
20
|
+
export const saturate = (x) => clamp(0, 1, x);
|
21
|
+
export const norm = (a, b, x) => (x - a) / ((b - a));
|
22
|
+
// https://www.sidefx.com/docs/houdini/expressions/fit.html
|
23
|
+
export const fit = (a, b, c, d, x) => lerp(c, d, saturate(norm(a, b, x)));
|
24
|
+
// https://www.sidefx.com/docs/houdini/expressions/efit.html
|
25
|
+
export const efit = (a, b, c, d, x) => lerp(c, d, norm(a, b, x));
|
26
|
+
// https://www.sidefx.com/docs/houdini/expressions/fit01.html
|
27
|
+
export const fit01 = (a, b, x) => lerp(a, b, saturate(x));
|
28
|
+
export const ewmabc = (beta = .8, t = 1) => {
|
29
|
+
let z = 0, bc = beta ** (t - 1);
|
30
|
+
return (x) => (z = lerp(x, z, beta)) / (1 - (bc *= beta));
|
31
|
+
};
|
32
|
+
export const sinc = (x) => x < Number.EPSILON ? 1.0 : Math.sin(x) / x;
|
33
|
+
export const nextpow2 = (x) => Math.ceil(Math.log2(Math.abs(x)));
|
34
|
+
export const mod = (x, m) => ((x % m) + m) % m;
|
35
|
+
export const logn = (n, x) => Math.log(x) / Math.log(n);
|
36
|
+
// https://www.desmos.com/calculator/ybbuznxbcc
|
37
|
+
export const floordiv = (x, b) => Math.floor(x / b + (x < 0 ? 1 : 0));
|
38
|
+
export const zoom = (x, s, p) => (x - p) * s + p;
|
39
|
+
export const align = (x, b) => (x + b - 1) & -b;
|
package/number.d.ts
ADDED
package/number.js
ADDED
package/object.d.ts
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
import type { RecordOf, Elements, Optional, Fn, FnV } from "./types.js";
|
2
|
+
export declare const mapEntries: <S, T = S>(f: FnV<[[string, S], number], [string, T]>) => Fn<RecordOf<S>, RecordOf<T>>;
|
3
|
+
export declare const mapValues: <S, T = S>(f: FnV<[S, string, number], T>) => Fn<RecordOf<S>, RecordOf<T>>;
|
4
|
+
export declare const rename: <S>(keys: RecordOf<string>) => Fn<RecordOf<S>, RecordOf<S>>;
|
5
|
+
export declare const renameWith: <S>(f: Fn<string, string>) => Fn<RecordOf<S>, RecordOf<S>>;
|
6
|
+
export declare const pick: <T extends RecordOf<any>, R extends Array<keyof T>>(obj: T, keys: R) => Pick<T, Elements<R>>;
|
7
|
+
export declare const omit: <T extends RecordOf<any>, R extends Array<keyof T>>(obj: T, keys: R) => Omit<T, Elements<R>>;
|
8
|
+
export declare const assoc: <T>(a: RecordOf<T>, [k, v]: [keyof T, T]) => RecordOf<T>;
|
9
|
+
type Merge<T extends RecordOf<unknown>, S extends RecordOf<unknown>, V> = {
|
10
|
+
[K in keyof (T & S)]: V;
|
11
|
+
};
|
12
|
+
export declare const merge: <T, S = T, V = T>(f: FnV<[Optional<T>, Optional<S>], V>) => <X extends RecordOf<T>, Y extends RecordOf<T>>(x: X, y: Y) => Merge<X, Y, V>;
|
13
|
+
export {};
|
package/object.js
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
export const mapEntries = (f) => obj => Object.fromEntries(Object.entries(obj).map(f));
|
2
|
+
export const mapValues = (f) => mapEntries(([k, v], i) => [k, f(v, k, i)]);
|
3
|
+
export const rename = (keys) => mapEntries(([k, v]) => [keys[k] ?? k, v]);
|
4
|
+
export const renameWith = (f) => mapEntries(([k, v]) => [f(k), v]);
|
5
|
+
export const pick = (obj, keys) => keys.reduce((a, k) => (a[k] = obj[k], a), {});
|
6
|
+
export const omit = (obj, keys) => pick(obj, Object.keys(obj).filter(k => !keys.includes(k)));
|
7
|
+
export const assoc = (a, [k, v]) => (a[k] = v, a);
|
8
|
+
export const merge = (f) => (x, y) => {
|
9
|
+
const keys = [...new Set(Object.keys(x).concat(Object.keys(y))).keys()];
|
10
|
+
return keys.reduce((a, k) => (a[k] = f(x[k], y[k]), a), {});
|
11
|
+
};
|
package/package.json
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
{
|
2
|
+
"name": "@cgtk/std",
|
3
|
+
"version": "0.0.182",
|
4
|
+
"type": "module",
|
5
|
+
"main": "./index.js",
|
6
|
+
"exports": {
|
7
|
+
".": "./index.js",
|
8
|
+
"./types": "./types.js",
|
9
|
+
"./checks": "./checks.js",
|
10
|
+
"./fn": "./fn.js",
|
11
|
+
"./object": "./object.js",
|
12
|
+
"./signal": "./signal.js",
|
13
|
+
"./assign": "./assign.js",
|
14
|
+
"./map": "./map.js",
|
15
|
+
"./array": "./array.js",
|
16
|
+
"./string": "./string.js",
|
17
|
+
"./number": "./number.js",
|
18
|
+
"./typedarray": "./typedarray.js",
|
19
|
+
"./async": "./async.js",
|
20
|
+
"./schedule": "./schedule.js",
|
21
|
+
"./iterable": "./iterable.js",
|
22
|
+
"./gen": "./gen.js",
|
23
|
+
"./tree": "./tree.js",
|
24
|
+
"./treemap": "./treemap.js",
|
25
|
+
"./stream": "./stream.js",
|
26
|
+
"./progress": "./progress.js",
|
27
|
+
"./constants": "./constants.js",
|
28
|
+
"./http": "./http.js",
|
29
|
+
"./json": "./json.js",
|
30
|
+
"./dom": "./dom.js",
|
31
|
+
"./weak": "./weak.js",
|
32
|
+
"./math": "./math.js",
|
33
|
+
"./basen": "./basen.js",
|
34
|
+
"./struct": "./struct.js",
|
35
|
+
"./buffer": "./buffer.js",
|
36
|
+
"./utils": "./utils.js"
|
37
|
+
},
|
38
|
+
"devDependencies": {
|
39
|
+
"typescript": "^5.8.3"
|
40
|
+
},
|
41
|
+
"publishConfig": {
|
42
|
+
"access": "public"
|
43
|
+
}
|
44
|
+
}
|
package/progress.d.ts
ADDED
package/progress.js
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export {};
|
package/schedule.d.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
import type { Fn, FnV, Reactive } from './types';
|
2
|
+
export declare const raf: Reactive<number>;
|
3
|
+
export declare const timeout: (ms: number) => Reactive<void>;
|
4
|
+
export declare const schedule: <T>(s: Reactive<T>) => <F extends FnV>(f: F) => (...xs: Parameters<F>) => ReturnType<Fn<Parameters<F>>>;
|
5
|
+
export declare const debounce: <T>(sched?: Reactive<T>) => Reactive<T>;
|
6
|
+
export declare const reset: <T>(sched?: Reactive<T>) => Reactive<T>;
|
7
|
+
export declare const repeatedly: (sched?: Reactive<any>) => (f: Fn<void>) => () => any;
|
8
|
+
export declare const toggler: (f: Fn<void, Fn<void>>) => (x: boolean) => Fn<void>;
|
package/schedule.js
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
import { isUndefined, isDefined } from './checks';
|
2
|
+
import { comp, lazy, noop, bind, apply, call } from './fn';
|
3
|
+
export const raf = f => {
|
4
|
+
const id = requestAnimationFrame(f);
|
5
|
+
return () => cancelAnimationFrame(id);
|
6
|
+
};
|
7
|
+
export const timeout = (ms) => (f) => {
|
8
|
+
const id = setTimeout(f, ms);
|
9
|
+
return () => clearTimeout(id);
|
10
|
+
};
|
11
|
+
export const schedule = (s) => (f) => {
|
12
|
+
const g = bind(lazy, f);
|
13
|
+
return call(comp(apply(g), s));
|
14
|
+
};
|
15
|
+
export const debounce = (sched = raf) => {
|
16
|
+
let cancel;
|
17
|
+
const stop = () => { if (isDefined(cancel))
|
18
|
+
cancel(), cancel = undefined; };
|
19
|
+
return (f) => {
|
20
|
+
if (isUndefined(cancel))
|
21
|
+
cancel = sched((x) => (cancel = undefined, f(x)));
|
22
|
+
return stop;
|
23
|
+
};
|
24
|
+
};
|
25
|
+
export const reset = (sched = raf) => {
|
26
|
+
let cancel;
|
27
|
+
const stop = () => { if (isDefined(cancel))
|
28
|
+
cancel(), cancel = undefined; };
|
29
|
+
return (f) => {
|
30
|
+
stop();
|
31
|
+
cancel = sched(f);
|
32
|
+
return stop;
|
33
|
+
};
|
34
|
+
};
|
35
|
+
export const repeatedly = (sched = raf) => (f) => {
|
36
|
+
let cancel;
|
37
|
+
const g = () => (f(), (cancel = sched(g)));
|
38
|
+
cancel = sched(g);
|
39
|
+
return () => cancel();
|
40
|
+
};
|
41
|
+
export const toggler = (f) => {
|
42
|
+
let cancel = noop;
|
43
|
+
return (x) => (cancel(), (cancel = x ? f() : noop));
|
44
|
+
};
|
package/signal.d.ts
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
import type { Fn, FnV, Reactive, RecordOf } from "./types";
|
2
|
+
export type Signal<T> = Fn<T> & {
|
3
|
+
on: Reactive<T>;
|
4
|
+
};
|
5
|
+
export declare const create: <A>(f: Fn<A>, on: Reactive<A>) => Signal<A>;
|
6
|
+
export declare const signal: <T>(fns?: Set<Fn<T>>) => Signal<T>;
|
7
|
+
export interface Value<T> {
|
8
|
+
value: T;
|
9
|
+
on: Reactive<T>;
|
10
|
+
op: <F extends FnV>(f: Fn<T, F>) => F;
|
11
|
+
ops: <F extends RecordOf<FnV>>(f: Fn<T, F>) => F;
|
12
|
+
set: Fn<T>;
|
13
|
+
update: Fn;
|
14
|
+
}
|
15
|
+
export declare const value: <T>(x: T) => Value<T>;
|
16
|
+
export type Values<T extends RecordOf<any>> = {
|
17
|
+
[key in keyof T]: Value<T[key]>;
|
18
|
+
};
|
19
|
+
export declare const values: <T extends RecordOf<any>>(vals: T) => Values<T>;
|
package/signal.js
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
import { after, constantly, noop } from "./fn";
|
2
|
+
import { mapValues } from "./object";
|
3
|
+
export const create = (f, on) => {
|
4
|
+
const g = f;
|
5
|
+
g.on = on;
|
6
|
+
return g;
|
7
|
+
};
|
8
|
+
export const signal = (fns = new Set()) => create((x) => fns.forEach(f => f(x)), (f) => (fns.add(f), () => fns.delete(f)));
|
9
|
+
;
|
10
|
+
export const value = (x) => {
|
11
|
+
const sig = signal();
|
12
|
+
const notify = after(() => sig(x));
|
13
|
+
const op = (f) => notify(f(x));
|
14
|
+
const mop = mapValues(notify);
|
15
|
+
return {
|
16
|
+
get value() { return x; },
|
17
|
+
set value(y) { sig(x = y); },
|
18
|
+
op,
|
19
|
+
on: (f) => (f(x), sig.on(f)),
|
20
|
+
ops: (f) => mop(f(x)),
|
21
|
+
set: op(constantly((y) => x = y)),
|
22
|
+
update: op(constantly(noop))
|
23
|
+
};
|
24
|
+
};
|
25
|
+
export const values = (vals) => mapValues(value)(vals);
|
package/stream.d.ts
ADDED
@@ -0,0 +1,6 @@
|
|
1
|
+
import type { Fn } from "./types";
|
2
|
+
export declare const readable: <T>(x: T) => ReadableStream<any>;
|
3
|
+
export declare function iterate<T>(rs: ReadableStream<T>): AsyncGenerator<Awaited<T>, void, unknown>;
|
4
|
+
export declare const map: <T, S>(f: Fn<T, S>) => TransformStream<T, S>;
|
5
|
+
export declare const tap: <T>(start: TransformerStartCallback<T> | undefined, t: Fn<T>, flush?: TransformerFlushCallback<T>) => TransformStream<T, any>;
|
6
|
+
export declare const reduceArray: <T>(stream: ReadableStream<T>, xs?: T[]) => Promise<T[]>;
|
package/stream.js
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { push } from "./array";
|
2
|
+
import { reduceA } from "./iterable";
|
3
|
+
export const readable = (x) => new ReadableStream({
|
4
|
+
start: c => (c.enqueue(x), c.close())
|
5
|
+
});
|
6
|
+
export async function* iterate(rs) {
|
7
|
+
const reader = rs.getReader();
|
8
|
+
try {
|
9
|
+
let x = await reader.read();
|
10
|
+
while (!x.done)
|
11
|
+
yield x.value, x = await reader.read();
|
12
|
+
}
|
13
|
+
finally {
|
14
|
+
reader.releaseLock();
|
15
|
+
}
|
16
|
+
}
|
17
|
+
export const map = (f) => new TransformStream({ transform(x, c) { c.enqueue(f(x)); } });
|
18
|
+
export const tap = (start, t, flush) => new TransformStream({
|
19
|
+
start,
|
20
|
+
transform(x, c) {
|
21
|
+
t(x);
|
22
|
+
c.enqueue(x);
|
23
|
+
},
|
24
|
+
flush
|
25
|
+
});
|
26
|
+
export const reduceArray = (stream, xs = []) => reduceA((push), xs)(iterate(stream));
|
package/string.d.ts
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
export declare const basename: (path: string) => string;
|
2
|
+
export declare const dirname: (path: string) => string;
|
3
|
+
export declare const objectURL: (data: Uint8Array, type: string) => string;
|
4
|
+
export declare const decode: (label?: string, opts?: TextDecoderOptions) => (x: Uint8Array, stream?: boolean) => string;
|
5
|
+
export declare const readLine: (delims?: Set<number>) => (data: Uint8Array, offset?: number) => string;
|
package/string.js
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
import { EMPTY } from "./constants";
|
2
|
+
import { seek } from "./array";
|
3
|
+
export const basename = (path) => path.split("/").at(-1) ?? "";
|
4
|
+
export const dirname = (path) => {
|
5
|
+
const parts = path.split("/");
|
6
|
+
parts.pop();
|
7
|
+
return parts.join("/");
|
8
|
+
};
|
9
|
+
export const objectURL = (data, type) => URL.createObjectURL(new Blob([data], { type }));
|
10
|
+
export const decode = (label = "utf-8", opts = {
|
11
|
+
fatal: false, ignoreBOM: false
|
12
|
+
}) => {
|
13
|
+
const decoder = new TextDecoder(label, opts);
|
14
|
+
return (x, stream = false) => decoder.decode(x, { stream });
|
15
|
+
};
|
16
|
+
export const readLine = (delims = new Set([0x0A])) => {
|
17
|
+
const dec = decode();
|
18
|
+
return (data, offset = 0) => {
|
19
|
+
const n = seek(data, delims, offset);
|
20
|
+
return n > 0 ? dec(data.subarray(offset, n + 1)) : EMPTY.STR;
|
21
|
+
};
|
22
|
+
};
|
package/struct.d.ts
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
import type { TypedArray } from "./types";
|
2
|
+
export interface View<T> {
|
3
|
+
(buf?: ArrayBuffer, offset?: number, length?: number): T;
|
4
|
+
size: number;
|
5
|
+
align: number;
|
6
|
+
}
|
7
|
+
type Inner<T> = T extends View<infer U> ? U : never;
|
8
|
+
type Num<T extends TypedArray> = View<T> & {
|
9
|
+
length: 1;
|
10
|
+
};
|
11
|
+
export declare const u8: Num<Uint8Array<ArrayBufferLike>>;
|
12
|
+
export declare const u16: Num<Uint16Array<ArrayBufferLike>>;
|
13
|
+
export declare const u32: Num<Uint32Array<ArrayBufferLike>>;
|
14
|
+
export declare const i8: Num<Int8Array<ArrayBufferLike>>;
|
15
|
+
export declare const i16: Num<Int16Array<ArrayBufferLike>>;
|
16
|
+
export declare const i32: Num<Int32Array<ArrayBufferLike>>;
|
17
|
+
export declare const f32: Num<Float32Array<ArrayBufferLike>>;
|
18
|
+
export declare const f64: Num<Float64Array<ArrayBufferLike>>;
|
19
|
+
export declare const vec: <T extends TypedArray, N extends number>(t: Num<T>, length: N, align?: number, size?: number) => View<T>;
|
20
|
+
export declare const array: <T>(type: View<T>, length: number, size?: number, align?: number) => View<T[]>;
|
21
|
+
type Struct<T extends ReadonlyArray<readonly [string, View<any>]>> = View<{
|
22
|
+
[K in T[number] as K[0]]: K[1] extends Num<any> ? number : Inner<K[1]>;
|
23
|
+
}>;
|
24
|
+
export declare const struct: <T extends ReadonlyArray<readonly [string, View<any>]>>(fs: T) => Struct<T>;
|
25
|
+
export {};
|
package/struct.js
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
import { align as _align } from "./math";
|
2
|
+
import { isTypedArray } from "./checks";
|
3
|
+
import * as TA from "./typedarray";
|
4
|
+
const property = (value) => ({
|
5
|
+
enumerable: true,
|
6
|
+
...(isTypedArray(value) && value.length == 1 ? {
|
7
|
+
get: () => value[0],
|
8
|
+
set: (x) => value[0] = x,
|
9
|
+
} : { value })
|
10
|
+
});
|
11
|
+
const num = (t) => {
|
12
|
+
const f = ((buf, offset, length = 1) => new t(buf, offset, length));
|
13
|
+
f.size = t.BYTES_PER_ELEMENT;
|
14
|
+
f.align = t.BYTES_PER_ELEMENT;
|
15
|
+
return f;
|
16
|
+
};
|
17
|
+
export const u8 = num(Uint8Array);
|
18
|
+
export const u16 = num(Uint16Array);
|
19
|
+
export const u32 = num(Uint32Array);
|
20
|
+
export const i8 = num(Int8Array);
|
21
|
+
export const i16 = num(Int16Array);
|
22
|
+
export const i32 = num(Int32Array);
|
23
|
+
export const f32 = num(Float32Array);
|
24
|
+
export const f64 = num(Float64Array);
|
25
|
+
export const vec = (t, length, align = t.align, size = t.size * length) => {
|
26
|
+
const f = ((buf = new ArrayBuffer(size), offset = 0) => t(buf, offset, length));
|
27
|
+
f.size = _align(size, align);
|
28
|
+
f.align = align;
|
29
|
+
return f;
|
30
|
+
};
|
31
|
+
export const array = (type, length, size = type.size * length, align = type.align) => {
|
32
|
+
const f = ((buf = new ArrayBuffer(size), offset = 0) => Array.from({ length }, (_, i) => type(buf, offset + i * _align(type.size, type.align))));
|
33
|
+
f.size = size;
|
34
|
+
f.align = align;
|
35
|
+
return f;
|
36
|
+
};
|
37
|
+
export const struct = (fs) => {
|
38
|
+
let align = 0, offset = 0;
|
39
|
+
const fields = {}, offsets = {};
|
40
|
+
for (const [name, type] of fs) {
|
41
|
+
align = Math.max(align, type.align);
|
42
|
+
offset = _align(offset, type.align);
|
43
|
+
fields[name] = type;
|
44
|
+
offsets[name] = offset;
|
45
|
+
offset += type.size;
|
46
|
+
}
|
47
|
+
const size = _align(offset, align);
|
48
|
+
const f = ((buf = new ArrayBuffer(size), offset = 0) => {
|
49
|
+
const res = {};
|
50
|
+
for (const [name, type] of Object.entries(fields)) {
|
51
|
+
Object.defineProperty(res, name, property(type(buf, offset + offsets[name])));
|
52
|
+
}
|
53
|
+
return res;
|
54
|
+
});
|
55
|
+
f.size = size;
|
56
|
+
f.align = align;
|
57
|
+
return f;
|
58
|
+
};
|
package/tree.d.ts
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
import type { Fn, FnV, TPred, PredV } from './types.js';
|
2
|
+
export type Node<S, T = S> = T | Tree<S, T>;
|
3
|
+
export type Tree<S, T = S> = [S, Node<S, T>[]];
|
4
|
+
export declare const tree: <S, T = S>(value: S, children?: Node<S, T>[]) => Tree<S, T>;
|
5
|
+
export declare const isTree: <S, T = S>(x: Node<S, T>) => x is Tree<S, T>;
|
6
|
+
export declare const children: <S, T = S>(p?: TPred<Tree<S, T>, Node<S, T>>) => (x: Node<S, T>) => Node<S, T>[];
|
7
|
+
export declare const value: <S, T = S>(p?: TPred<Tree<S, T>, Node<S, T>>) => (x: Node<S, T>) => S | T;
|
8
|
+
export declare const transform: <S, T = S, A = Tree<S, T>, B = Node<S, T>, C = void>(node: FnV<[Tree<S, T>, Fn<C, Fn<Node<S, T>>>, C], A>, leaf: FnV<[T, C], B>, p?: TPred<Tree<S, T>>) => Fn<C, Fn<Node<S, T>, A | B>>;
|
9
|
+
export declare const map: <S, T = S, U = S, V = T, C = void>(parent: FnV<[S, C], U>, child: FnV<[T, C], V>, update?: FnV<[C, S], C>, p?: TPred<Tree<S, T>>) => Fn<C, Fn<Node<S, T>, Node<U, V>>>;
|
10
|
+
export declare const filter: <S, T = S, C = void>(ps: PredV<[Node<S, T>, C]>, update?: FnV<[C, S], C>, p?: TPred<Tree<S, T>>) => Fn<C, Fn<Node<S, T>, T | Tree<S, T>>>;
|
11
|
+
export declare const toggleChildren: <S, T = S, C = void>(g: FnV<[Tree<S, T>, C], boolean>, update?: FnV<[C, S], C>, p?: TPred<Tree<S, T>>) => Fn<C, Fn<Node<S, T>, Node<S, T>>>;
|
12
|
+
type TreeObject<T extends Node<string>[]> = {
|
13
|
+
[K in T[number] as K extends string ? K : K[0]]: K extends Tree<string> ? {
|
14
|
+
value: string;
|
15
|
+
children: TreeObject<K[1]>;
|
16
|
+
} : string;
|
17
|
+
};
|
18
|
+
export declare const asObject: <T extends Node<string>[]>(items: T, f?: FnV<[string, string], string>, update?: FnV<[string, string], string>, context?: string) => TreeObject<T>;
|
19
|
+
export declare const zip: <S, T, U, V>(na: Node<S, T>[], nb: Node<U, V>[]) => Node<[S, U], [T, V]>[];
|
20
|
+
export {};
|