@cgtk/std 0.0.198 → 0.0.200
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 +1 -0
- package/array.js +1 -0
- package/channel.d.ts +2 -1
- package/channel.js +10 -6
- package/dom.d.ts +1 -1
- package/dom.js +14 -3
- package/fn.d.ts +2 -3
- package/fn.js +3 -8
- package/http.js +1 -1
- package/map.d.ts +1 -0
- package/map.js +1 -0
- package/package.json +1 -1
- package/rect.d.ts +3 -2
- package/rect.js +8 -10
- package/schedule.d.ts +0 -1
- package/schedule.js +1 -2
- package/scope.d.ts +0 -1
- package/scope.js +1 -3
- package/set.d.ts +1 -0
- package/set.js +2 -0
- package/string.d.ts +2 -1
- package/string.js +3 -1
- package/treemap.js +5 -9
- package/typedarray.d.ts +3 -2
- package/typedarray.js +26 -5
package/array.d.ts
CHANGED
package/array.js
CHANGED
package/channel.d.ts
CHANGED
|
@@ -3,7 +3,6 @@ export interface Channel<T> {
|
|
|
3
3
|
next: Fn<T>;
|
|
4
4
|
on(next: Fn<T>, done?: Dispose): Dispose;
|
|
5
5
|
done: Dispose;
|
|
6
|
-
stateful(f: Fn<T, Dispose>, done?: Dispose): Dispose;
|
|
7
6
|
to<S>(f: Fn<Channel<T>, Channel<S>>): Channel<S>;
|
|
8
7
|
}
|
|
9
8
|
export declare const create: <T>(subs?: Set<{
|
|
@@ -20,8 +19,10 @@ export declare const map: <T, S>(f: Fn<T, S>, ch?: Channel<S>) => Fn<Channel<T>,
|
|
|
20
19
|
export declare const filter: <T>(p: Pred<T>, ch?: Channel<T>) => Fn<Channel<T>, Channel<T>>;
|
|
21
20
|
export declare const then: <T>(ch?: Channel<T>) => Fn<Channel<Promise<T>>, Channel<T>>;
|
|
22
21
|
export declare const dedup: <T, S = T>(key?: Fn<T, S>, ch?: Channel<T>) => Fn<Channel<T>, Channel<T>>;
|
|
22
|
+
export declare const swapping: () => <T>(c: Channel<T>) => Channel<T>;
|
|
23
23
|
export declare const gen: <T>(f: FnV<[Fn<T>, Dispose], Dispose | void>, ch?: Channel<T>) => Channel<T>;
|
|
24
24
|
export declare const reduce: <T, S>(f: FnV<[S, T], S>, a: S, ch?: Channel<S>) => (c: Channel<T>) => Channel<S>;
|
|
25
|
+
export declare const clearing: <T>(c: Channel<T>) => Channel<T>;
|
|
25
26
|
export declare const flatten: <T>(ch?: Channel<T>) => (cs: Channel<Channel<T>>) => Channel<T>;
|
|
26
27
|
export declare const latest: <T>(ch?: Channel<T>) => (cs: Channel<Channel<T>>) => Channel<T>;
|
|
27
28
|
export declare const microOn: <T>(ch?: Channel<T>) => Channel<T>;
|
package/channel.js
CHANGED
|
@@ -4,10 +4,6 @@ import { add } from "./set.js";
|
|
|
4
4
|
const channel = (next, on, done = F.noop) => ({
|
|
5
5
|
next, on, done,
|
|
6
6
|
to(f) { return f(this); },
|
|
7
|
-
stateful(next, done = F.noop) {
|
|
8
|
-
const swap = F.swapping();
|
|
9
|
-
return on(swap(next), swap(done));
|
|
10
|
-
},
|
|
11
7
|
});
|
|
12
8
|
export const create = (subs = new Set()) => channel((x) => subs.forEach(s => s.next(x)), (next, done = F.noop) => {
|
|
13
9
|
const del = add(subs, { next, done });
|
|
@@ -42,18 +38,26 @@ export const dedup = (key = F.identity, ch) => pipe(next => {
|
|
|
42
38
|
x = k;
|
|
43
39
|
};
|
|
44
40
|
}, ch);
|
|
41
|
+
export const swapping = () => (c) => {
|
|
42
|
+
const swap = F.swapping();
|
|
43
|
+
return channel(c.next, (next, done = F.noop) => c.on(swap(next), swap(done)), c.done);
|
|
44
|
+
};
|
|
45
45
|
export const gen = (f, ch = create()) => {
|
|
46
46
|
let ended = false;
|
|
47
47
|
let done = () => { ended = true; };
|
|
48
48
|
done = F.forEach(f(ch.next, () => done()) ?? F.noop, ch.done);
|
|
49
49
|
return ended ? channel(F.noop, F.constantly(F.noop)) : channel(ch.next, ch.on, done);
|
|
50
50
|
};
|
|
51
|
-
export const reduce = (f, a, ch = create()) => (c) => channel(F.noop, ch.on,
|
|
51
|
+
export const reduce = (f, a, ch = create()) => (c) => channel(F.noop, (next, done = F.noop) => ch.on(next, F.forEach(() => next(a), done)), c.on(x => a = f(a, x), ch.done));
|
|
52
|
+
export const clearing = (c) => {
|
|
53
|
+
let clear = F.noop;
|
|
54
|
+
return channel(c.next, (next, done = F.noop) => c.on(x => clear = next(x) ?? F.noop, F.forEach(() => clear(), done)), c.done);
|
|
55
|
+
};
|
|
52
56
|
export const flatten = (ch = create()) => (cs) => {
|
|
53
57
|
const ds = new Set();
|
|
54
58
|
return channel(ch.next, ch.on, cs.on(c => (ds.add(c.done), c.on(ch.next)), F.forEach(ch.done, () => ds.forEach(d => d()))));
|
|
55
59
|
};
|
|
56
|
-
export const latest = (ch = create()) => (cs) => channel(ch.next, ch.on, cs.
|
|
60
|
+
export const latest = (ch = create()) => (cs) => channel(ch.next, ch.on, cs.to(swapping()).on(c => c.on(ch.next, c.done), ch.done));
|
|
57
61
|
export const microOn = (ch = create()) => channel(ch.next, (next, done = F.noop) => {
|
|
58
62
|
const ctrl = new AbortController();
|
|
59
63
|
let off = () => (ctrl.abort(), done());
|
package/dom.d.ts
CHANGED
|
@@ -49,7 +49,7 @@ export declare const preventDefault: <T extends Event>(e: T) => void;
|
|
|
49
49
|
export declare const loadImage: (img: HTMLImageElement, src: string) => Promise<HTMLImageElement>;
|
|
50
50
|
export declare const pushState: (path: string, query?: RecordOf<string>, data?: any) => void;
|
|
51
51
|
export declare const qs: (search?: string) => Maybe<RecordOf<string>>;
|
|
52
|
-
export declare const imageData: (img:
|
|
52
|
+
export declare const imageData: (img: ImageBitmap) => ImageData;
|
|
53
53
|
export type Child = ChildNode | string;
|
|
54
54
|
export declare const append: (el: ParentNode, ...children: Child[]) => () => void;
|
|
55
55
|
export type Attribs = Record<string, string | number | boolean>;
|
package/dom.js
CHANGED
|
@@ -41,9 +41,20 @@ export const qs = (search = location.search) => search.length > 0
|
|
|
41
41
|
? Object.fromEntries(new URLSearchParams(search).entries())
|
|
42
42
|
: undefined;
|
|
43
43
|
export const imageData = (img) => {
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
const canvas = new OffscreenCanvas(img.width, img.height);
|
|
45
|
+
const gl = canvas.getContext("webgl2");
|
|
46
|
+
const texture = gl.createTexture();
|
|
47
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
48
|
+
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, img.width, img.height);
|
|
49
|
+
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, img.width, img.height, gl.RGBA, gl.UNSIGNED_BYTE, img);
|
|
50
|
+
const fb = gl.createFramebuffer();
|
|
51
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
|
|
52
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
|
53
|
+
const pixels = new Uint8ClampedArray(img.width * img.height * 4);
|
|
54
|
+
gl.readPixels(0, 0, img.width, img.height, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
55
|
+
gl.deleteFramebuffer(fb);
|
|
56
|
+
gl.deleteTexture(texture);
|
|
57
|
+
return new ImageData(pixels, img.width, img.height);
|
|
47
58
|
};
|
|
48
59
|
export const append = (el, ...children) => {
|
|
49
60
|
const els = children.map(x => isString(x) ? document.createTextNode(x) : x);
|
package/fn.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { Fn, FnV, FnF, Pred, Last, Lazy, Dispose, Reactive, Promisified, Ma
|
|
|
2
2
|
export declare const tee: <T>(f: Fn<T, void>) => Fn<T, T>;
|
|
3
3
|
export declare const comp: <Fs extends Fn[]>(...fs: Fs) => (x: Fs[0] extends Fn<infer T> ? T : never) => Last<Fs> extends Fn<any, infer R> ? R : never;
|
|
4
4
|
export declare const pipe: <T, Fs extends [Fn<T>, ...Fn[]]>(x: T, ...fs: Fs) => Last<Fs> extends Fn<any, infer R> ? R : never;
|
|
5
|
-
export declare const forEach: <T, R = any>(...fs:
|
|
5
|
+
export declare const forEach: <T extends any[], R = any>(...fs: FnV<T, R>[]) => (...x: T) => void;
|
|
6
6
|
export declare const and: <T>(...fs: Pred<T>[]) => (x: T) => boolean;
|
|
7
7
|
export declare const or: <T>(...fs: Pred<T>[]) => (x: T) => boolean;
|
|
8
8
|
export declare const not: <T>(p: Pred<T>) => (x: T) => boolean;
|
|
@@ -18,13 +18,12 @@ export declare const before: <F extends Fn<void>>(f: F) => FnF;
|
|
|
18
18
|
export declare const after: <F extends Fn<void>>(f: F) => FnF;
|
|
19
19
|
export declare const filter: <T>(p: Pred<T>, f: Fn<T>) => (x: T) => void;
|
|
20
20
|
export declare const scan: <T, S>(f: FnV<[S, T], S>, a: S) => Fn<T, S>;
|
|
21
|
-
export declare const memoize: <T extends any[], K, V>(f: FnV<T, V>, key?: FnV<T, K>, cache?: Map<K, V>) => (...xs: T) =>
|
|
21
|
+
export declare const memoize: <T extends any[], K, V>(f: FnV<T, V>, key?: FnV<T, K>, cache?: Map<K, V>) => (...xs: T) => V;
|
|
22
22
|
export declare const abortable: <T = any>(f: Fn<AbortSignal>) => (reason?: T) => void;
|
|
23
23
|
export declare const disposable: (f: Fn<Fn<Dispose, Dispose>>, disposes?: Set<Dispose>) => Dispose;
|
|
24
24
|
export declare const swapping: () => <F extends FnV<any[], Dispose | void>>(f: F) => FnV<Parameters<F>, Dispose>;
|
|
25
25
|
export declare const idemp: <F extends FnV<any[], Dispose | void>>(d: Fn<Dispose, Dispose>, f: F) => FnV<Parameters<F>, Dispose>;
|
|
26
26
|
export declare const toggler: (f: Fn<void, Dispose>) => Fn<boolean, Dispose>;
|
|
27
|
-
export declare const voidify: <F extends FnV>(f: F) => (...xs: Parameters<F>) => void;
|
|
28
27
|
export declare const effectual: <T>(f: Reactive<T>, g: Fn<T>) => Dispose;
|
|
29
28
|
export declare const promisify: <F extends FnV>(f: F) => (...xs: Parameters<F>) => Promisified<ReturnType<F>>;
|
|
30
29
|
export declare const then: <T, F extends FnV<any, MaybePromise<any>>>(f: F, g?: Fn<Awaited<ReturnType<F>>, T>) => (...xs: Parameters<F>) => Promise<T>;
|
package/fn.js
CHANGED
|
@@ -4,7 +4,8 @@ import { isPromise } from "./checks.js";
|
|
|
4
4
|
export const tee = f => x => (f(x), x);
|
|
5
5
|
export const comp = (...fs) => (x) => fs.reduce((x, f) => f(x), x);
|
|
6
6
|
export const pipe = (x, ...fs) => fs.reduce((x, f) => f(x), x);
|
|
7
|
-
export const forEach = (...fs) => (x) => fs.forEach(f => f(x));
|
|
7
|
+
// export const forEach = <T, R = any>(...fs: Fn<T, R>[]) => (x: T) => fs.forEach(f => f(x));
|
|
8
|
+
export const forEach = (...fs) => (...x) => fs.forEach(f => f(...x));
|
|
8
9
|
export const and = (...fs) => (x) => fs.reduce((a, f) => a && f(x), true);
|
|
9
10
|
export const or = (...fs) => (x) => fs.reduce((a, f) => a || f(x), false);
|
|
10
11
|
export const not = (p) => (x) => !p(x);
|
|
@@ -25,12 +26,7 @@ export const after = (f) => g => (...xs) => {
|
|
|
25
26
|
export const filter = (p, f) => (x) => { if (p(x))
|
|
26
27
|
f(x); };
|
|
27
28
|
export const scan = (f, a) => (x) => a = f(a, x);
|
|
28
|
-
export const memoize = (f, key = (...xs) => xs[0], cache = new Map()) => (...xs) =>
|
|
29
|
-
const k = key(...xs);
|
|
30
|
-
if (!cache.has(k))
|
|
31
|
-
cache.set(k, f(...xs));
|
|
32
|
-
return cache.get(k);
|
|
33
|
-
};
|
|
29
|
+
export const memoize = (f, key = (...xs) => xs[0], cache = new Map()) => (...xs) => cache.getOrInsertComputed(key(...xs), () => f(...xs));
|
|
34
30
|
export const abortable = (f) => {
|
|
35
31
|
const ctrl = new AbortController();
|
|
36
32
|
f(ctrl.signal);
|
|
@@ -54,7 +50,6 @@ export const toggler = (f) => {
|
|
|
54
50
|
const stop = () => cancel();
|
|
55
51
|
return (x) => (stop(), (cancel = x ? f() : noop), stop);
|
|
56
52
|
};
|
|
57
|
-
export const voidify = (f) => (...xs) => { f(...xs); };
|
|
58
53
|
export const effectual = (f, g) => disposable(d => d(f(idemp(d, g))));
|
|
59
54
|
export const promisify = (f) => (...xs) => Async.promisify(f(...xs));
|
|
60
55
|
export const then = (f, g = identity) => (...xs) => {
|
package/http.js
CHANGED
|
@@ -21,7 +21,7 @@ export const fetchImage = (src) => new Promise((resolve, reject) => {
|
|
|
21
21
|
export const fetchImageBitmap = async (url, init) => fetch(url, init)
|
|
22
22
|
.then(tee(assertStatus(200)))
|
|
23
23
|
.then(resp => resp.blob())
|
|
24
|
-
.then(blob => createImageBitmap(blob, { colorSpaceConversion: "none" }));
|
|
24
|
+
.then(blob => createImageBitmap(blob, { colorSpaceConversion: "none", premultiplyAlpha: "none" }));
|
|
25
25
|
export const fetchJSON = (url, init) => fetchText(url, init).then(JSON.parse);
|
|
26
26
|
export const fetchDataUrl = (url, init) => fetch(url, init)
|
|
27
27
|
.then(tee(assertStatus(200)))
|
package/map.d.ts
CHANGED
|
@@ -10,3 +10,4 @@ export declare const update: <K, V>(m: Map<K, V>, k: K, f: FnV<[V | undefined, K
|
|
|
10
10
|
export declare const first: <K, V>(m: Map<K, V>) => Maybe<V>;
|
|
11
11
|
export declare const shift: <K, V>(m: Map<K, V>) => Maybe<[K, V]>;
|
|
12
12
|
export declare const reduce: <K, V, T>(m: Map<K, V>, f: FnV<[T, V, K, Map<K, V>], T>, a: T) => T;
|
|
13
|
+
export declare const mapValues: <K, T, S>(m: Map<K, T>, f: FnV<[T, K], S>) => Map<K, S>;
|
package/map.js
CHANGED
package/package.json
CHANGED
package/rect.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Tuple } from "./types.js";
|
|
2
2
|
export type Rect = Tuple<number, 4>;
|
|
3
3
|
export declare const rect: (x: number, y: number, w: number, h: number) => Rect;
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const
|
|
4
|
+
export declare const aspect: ([_x, _y, w, h]: Rect) => number;
|
|
5
|
+
export declare const vsplit: (ratio: number[], [x, y, w, h]: Rect) => Rect[];
|
|
6
|
+
export declare const hsplit: (ratio: number[], [x, y, w, h]: Rect) => Rect[];
|
package/rect.js
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { add } from "./number.js";
|
|
2
|
+
import { push, pop } from "./array.js";
|
|
2
3
|
export const rect = (x, y, w, h) => [x, y, w, h];
|
|
3
|
-
export const
|
|
4
|
+
export const aspect = ([_x, _y, w, h]) => w / h;
|
|
5
|
+
export const vsplit = (ratio, [x, y, w, h]) => {
|
|
4
6
|
const tot = ratio.reduce(add, 0);
|
|
5
|
-
const cum = [0];
|
|
6
|
-
ratio.
|
|
7
|
-
cum.pop();
|
|
8
|
-
return (i) => ([x, _, w, h]) => [x, cum[i] * h, w, ratio[i] / tot * h];
|
|
7
|
+
const cum = pop(ratio.reduce((a, x) => push(a, x / tot + a.at(-1)), [0]));
|
|
8
|
+
return ratio.map((r, i) => [x, y + cum[i] * h, w, r / tot * h]);
|
|
9
9
|
};
|
|
10
|
-
export const
|
|
10
|
+
export const hsplit = (ratio, [x, y, w, h]) => {
|
|
11
11
|
const tot = ratio.reduce(add, 0);
|
|
12
|
-
const cum = [0];
|
|
13
|
-
ratio.
|
|
14
|
-
cum.pop();
|
|
15
|
-
return (i) => ([_, y, w, h]) => [cum[i] * w, y, ratio[i] / tot * w, h];
|
|
12
|
+
const cum = pop(ratio.reduce((a, x) => push(a, x / tot + a.at(-1)), [0]));
|
|
13
|
+
return ratio.map((r, i) => [x + cum[i] * w, y, r / tot * w, h]);
|
|
16
14
|
};
|
package/schedule.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import type { Dispose, Fn, FnV, Reactive } from './types.js';
|
|
|
2
2
|
export declare const raf: Reactive<number>;
|
|
3
3
|
export declare const timeout: (ms?: number) => Reactive<void>;
|
|
4
4
|
export declare const schedule: <T>(s: Reactive<T>) => <F extends FnV>(f: F) => FnV<Parameters<F>, Dispose>;
|
|
5
|
-
export declare const idempotent: <T>(s: Reactive<T>, d: Fn<Dispose, Dispose>) => <F extends FnV>(f: F) => FnV<Parameters<F>, Dispose>;
|
|
6
5
|
export declare const debounce: <T>(sched?: Reactive<T>) => Reactive<T>;
|
|
7
6
|
export declare const reset: <T>(sched?: Reactive<T>) => Reactive<T>;
|
|
8
7
|
export declare const repeatedly: <T = number>(sched?: Reactive<T>) => (f: Fn<T, boolean | void>) => () => any;
|
package/schedule.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { isUndefined, isDefined, counted } from './checks.js';
|
|
2
|
-
import { comp, lazy, bind, apply, call, where,
|
|
2
|
+
import { comp, lazy, bind, apply, call, where, noop, abortable } from './fn.js';
|
|
3
3
|
export const raf = f => bind(cancelAnimationFrame, requestAnimationFrame(f));
|
|
4
4
|
export const timeout = (ms = 0) => f => bind(clearTimeout, setTimeout(f, ms));
|
|
5
5
|
export const schedule = (s) => (f) => call(comp(apply(bind((lazy), f)), s));
|
|
6
|
-
export const idempotent = (s, d) => (f) => swapping()((...xs) => d(s(() => f(...xs))));
|
|
7
6
|
export const debounce = (sched = raf) => {
|
|
8
7
|
let cancel;
|
|
9
8
|
const stop = () => { if (isDefined(cancel))
|
package/scope.d.ts
CHANGED
|
@@ -14,6 +14,5 @@ export declare const compose: <R extends Structure<Scope<any>>>(rs: R) => Scope<
|
|
|
14
14
|
export declare const of: <T>(x: T, f: Fn<T, Dispose>) => Scope<T>;
|
|
15
15
|
type Use = <T>(r: Scope<T>) => T;
|
|
16
16
|
export declare const gen: <R>(f: FnV<[Use, Fn<Dispose, Dispose>], R>) => Scope<R>;
|
|
17
|
-
export declare const consume: (f: Fn<Use, Dispose | void>) => Dispose;
|
|
18
17
|
export declare const worker: (w: Worker) => Scope<Worker>;
|
|
19
18
|
export {};
|
package/scope.js
CHANGED
|
@@ -29,13 +29,11 @@ export const compose = (rs) => {
|
|
|
29
29
|
}
|
|
30
30
|
return Object.fromEntries(Object.entries(rs).map(([k, v]) => [k, rec(v)]));
|
|
31
31
|
};
|
|
32
|
-
|
|
33
|
-
return scope(value, F.forEach(...disposes));
|
|
32
|
+
return scope(rec(rs), F.forEach(...disposes));
|
|
34
33
|
};
|
|
35
34
|
export const of = (x, f) => scope(x, f(x));
|
|
36
35
|
export const gen = (f) => {
|
|
37
36
|
const res = new Set();
|
|
38
37
|
return scope(f(r => (res.add(r.dispose), r.value), F.bind(add, res)), () => res.forEach(f => f()));
|
|
39
38
|
};
|
|
40
|
-
export const consume = (f) => F.disposable(use => use(f(r => (use(r.dispose), r.value)) ?? F.noop));
|
|
41
39
|
export const worker = (w) => of(w, x => x.terminate.bind(x));
|
package/set.d.ts
CHANGED
package/set.js
CHANGED
package/string.d.ts
CHANGED
|
@@ -6,4 +6,5 @@ export declare const objectURL: (data: Uint8Array<ArrayBuffer>, type: string) =>
|
|
|
6
6
|
export declare const decode: (label?: string, opts?: TextDecoderOptions) => (x: Uint8Array, stream?: boolean) => string;
|
|
7
7
|
export declare const readLine: (delims?: Set<number>) => (data: Uint8Array, offset?: number) => string;
|
|
8
8
|
export declare const DATA_URL: RegExp;
|
|
9
|
-
export declare const
|
|
9
|
+
export declare const camelTo: (s: string, delim?: string) => string;
|
|
10
|
+
export declare const join: (sep: string, ...xs: Array<string | undefined>) => string;
|
package/string.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { EMPTY } from "./constants.js";
|
|
2
2
|
import { seek } from "./array.js";
|
|
3
|
+
import { isDefined } from "./checks.js";
|
|
3
4
|
export const basename = (path) => path.split("/").at(-1) ?? "";
|
|
4
5
|
export const dirname = (path) => {
|
|
5
6
|
const parts = path.split("/");
|
|
@@ -27,4 +28,5 @@ export const readLine = (delims = new Set([0x0A])) => {
|
|
|
27
28
|
};
|
|
28
29
|
};
|
|
29
30
|
export const DATA_URL = /^data:(?<mime>[\w/\-\+]+)?(;(?<params>[\w\-]+\=[^;,\s]+)*)?(;(?<encoding>base64))?,(?<data>.*)$/;
|
|
30
|
-
export const
|
|
31
|
+
export const camelTo = (s, delim = "-") => s.replace(/[A-Z]/g, m => delim + m.toLowerCase());
|
|
32
|
+
export const join = (sep, ...xs) => xs.filter(isDefined).join(sep);
|
package/treemap.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { before } from "./fn.js";
|
|
2
2
|
import { isDefined } from "./checks.js";
|
|
3
|
-
import { EMPTY } from "./constants.js";
|
|
4
3
|
export const treemap = () => {
|
|
5
4
|
const nodes = new Set();
|
|
6
5
|
const parents = new Map();
|
|
@@ -10,20 +9,17 @@ export const treemap = () => {
|
|
|
10
9
|
const hasChanged = changed;
|
|
11
10
|
if (hasChanged) {
|
|
12
11
|
children.clear();
|
|
13
|
-
|
|
12
|
+
nodes.forEach(k => {
|
|
14
13
|
const p = parents.get(k);
|
|
15
|
-
if (isDefined(p))
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
children.get(p).push(k);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
14
|
+
if (isDefined(p))
|
|
15
|
+
children.getOrInsert(p, []).push(k);
|
|
16
|
+
});
|
|
21
17
|
changed = false;
|
|
22
18
|
}
|
|
23
19
|
return hasChanged;
|
|
24
20
|
};
|
|
25
21
|
const updated = before(update);
|
|
26
|
-
const getChildren = updated((key) => children.
|
|
22
|
+
const getChildren = updated((key) => children.getOrInsert(key, []));
|
|
27
23
|
const parent = updated((key) => parents.get(key));
|
|
28
24
|
const roots = () => nodes.values().filter(k => !parents.has(k));
|
|
29
25
|
return {
|
package/typedarray.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FnV, TypedArray, NumberArray, BufferType, Number } from "./types.js";
|
|
1
|
+
import type { FnV, TypedArray, NumberArray, BufferType, Number, Tuple } from "./types.js";
|
|
2
2
|
export interface Constructor<T extends TypedArray> {
|
|
3
3
|
new (length: number): T;
|
|
4
4
|
new (buffer: BufferType<T> | ArrayBufferLike, byteOffset?: number, length?: number): T;
|
|
@@ -24,7 +24,8 @@ export declare const ctor: <T extends TypedArray>(x: T) => Constructor<T>;
|
|
|
24
24
|
export declare const emptyLike: <T extends TypedArray>(x: T) => T;
|
|
25
25
|
export declare const set: <T extends TypedArray>(xs: T, x: ArrayLike<Number<T>> | T, i: number) => T;
|
|
26
26
|
export declare const concat: <T extends TypedArray>(chunks: T[]) => T;
|
|
27
|
-
export declare const
|
|
27
|
+
export declare const extent: (arr: NumberArray) => Tuple<number, 2>;
|
|
28
|
+
export declare const iter: <T extends TypedArray>(data: T, size: number, stride?: number, loop?: boolean) => Generator<T>;
|
|
28
29
|
export declare const tile: (n: number) => (out: TypedArray, x: TypedArray) => TypedArray;
|
|
29
30
|
export declare const tileEvery: (m: number, n: number) => <T extends TypedArray>(xs: T, out?: T) => T;
|
|
30
31
|
export declare const strided: <T extends TypedArray>(data: T, size: number, stride?: number, out?: T) => T;
|
package/typedarray.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { bind } from "./fn.js";
|
|
2
2
|
import { zmap } from "./iterable.js";
|
|
3
|
-
import { push } from "./array.js";
|
|
3
|
+
import { push, tuple } from "./array.js";
|
|
4
4
|
export const view = (type, length) => (buf = new ArrayBuffer(type.BYTES_PER_ELEMENT * length), offset = 0) => new type(buf, offset, length);
|
|
5
5
|
export const u8 = bind((view), Uint8Array);
|
|
6
6
|
export const u16 = bind((view), Uint16Array);
|
|
@@ -22,11 +22,32 @@ export const concat = (chunks) => {
|
|
|
22
22
|
chunks.reduce((offset, chunk) => (out.set(chunk, offset), offset + chunk.length), 0);
|
|
23
23
|
return out;
|
|
24
24
|
};
|
|
25
|
-
export const
|
|
25
|
+
export const extent = (arr) => {
|
|
26
|
+
let min = Number.POSITIVE_INFINITY, max = Number.NEGATIVE_INFINITY;
|
|
27
|
+
arr.forEach(x => (min = Math.min(min, x), max = Math.max(max, x)));
|
|
28
|
+
return tuple(min, max);
|
|
29
|
+
};
|
|
30
|
+
export const iter = function* (data, size, stride = size, loop = false) {
|
|
26
31
|
const C = ctor(data);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
if (loop) {
|
|
33
|
+
for (let i = 0, n = data.length; i < n; i += stride) {
|
|
34
|
+
if (i + size < n) {
|
|
35
|
+
const offset = data.byteOffset + i * C.BYTES_PER_ELEMENT;
|
|
36
|
+
yield new C(data.buffer, offset, size);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
const buf = new C(size);
|
|
40
|
+
for (let j = 0; j < size; j++)
|
|
41
|
+
buf[j] = data[(i + j) % n];
|
|
42
|
+
yield buf;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
for (let i = 0, n = data.length; i < n - size + 1; i += stride) {
|
|
48
|
+
const offset = data.byteOffset + i * C.BYTES_PER_ELEMENT;
|
|
49
|
+
yield new C(data.buffer, offset, size);
|
|
50
|
+
}
|
|
30
51
|
}
|
|
31
52
|
};
|
|
32
53
|
export const tile = (n) => (out, x) => {
|