@cgtk/std 0.0.192 → 0.0.194

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/array.d.ts +1 -1
  2. package/array.js +1 -1
  3. package/assign.d.ts +1 -1
  4. package/assign.js +1 -1
  5. package/async.d.ts +3 -3
  6. package/async.js +5 -4
  7. package/basen.js +1 -1
  8. package/buffer.d.ts +1 -1
  9. package/buffer.js +1 -1
  10. package/checks.d.ts +2 -2
  11. package/checks.js +2 -2
  12. package/dom.d.ts +2 -2
  13. package/dom.js +3 -3
  14. package/fn.d.ts +3 -3
  15. package/fn.js +3 -3
  16. package/http.d.ts +6 -7
  17. package/http.js +11 -15
  18. package/iterable.d.ts +1 -1
  19. package/iterable.js +3 -3
  20. package/json.d.ts +1 -1
  21. package/json.js +1 -1
  22. package/map.d.ts +3 -3
  23. package/map.js +2 -2
  24. package/math.js +1 -1
  25. package/npy.d.ts +1 -1
  26. package/number.js +1 -1
  27. package/object.d.ts +2 -2
  28. package/package.json +2 -2
  29. package/port.d.ts +2 -1
  30. package/port.js +7 -4
  31. package/progress.d.ts +1 -1
  32. package/rect.d.ts +1 -1
  33. package/rect.js +1 -1
  34. package/resource.d.ts +10 -8
  35. package/resource.js +22 -15
  36. package/schedule.d.ts +1 -1
  37. package/schedule.js +2 -2
  38. package/set.d.ts +1 -0
  39. package/set.js +1 -0
  40. package/signal.d.ts +18 -5
  41. package/signal.js +56 -15
  42. package/src/array.d.ts +14 -0
  43. package/src/array.js +21 -0
  44. package/src/assign.d.ts +8 -0
  45. package/src/assign.js +26 -0
  46. package/src/async.d.ts +8 -0
  47. package/src/async.js +31 -0
  48. package/src/base64.d.ts +1 -0
  49. package/src/base64.js +7 -0
  50. package/src/basen.d.ts +12 -0
  51. package/src/basen.js +31 -0
  52. package/src/buffer.d.ts +14 -0
  53. package/src/buffer.js +54 -0
  54. package/src/checks.d.ts +29 -0
  55. package/src/checks.js +44 -0
  56. package/src/constants.d.ts +5 -0
  57. package/src/constants.js +1 -0
  58. package/src/dom.d.ts +50 -0
  59. package/src/dom.js +36 -0
  60. package/src/fn.d.ts +33 -0
  61. package/src/fn.js +61 -0
  62. package/src/http.d.ts +9 -0
  63. package/src/http.js +33 -0
  64. package/src/index.d.ts +1 -0
  65. package/src/index.js +1 -0
  66. package/src/iterable.d.ts +43 -0
  67. package/src/iterable.js +158 -0
  68. package/src/json.d.ts +1 -0
  69. package/src/json.js +1 -0
  70. package/src/map.d.ts +12 -0
  71. package/src/map.js +35 -0
  72. package/src/math.d.ts +34 -0
  73. package/src/math.js +43 -0
  74. package/src/npy.d.ts +10 -0
  75. package/src/npy.js +29 -0
  76. package/src/number.d.ts +4 -0
  77. package/src/number.js +13 -0
  78. package/src/object.d.ts +15 -0
  79. package/src/object.js +13 -0
  80. package/src/port.d.ts +30 -0
  81. package/src/port.js +56 -0
  82. package/src/progress.d.ts +6 -0
  83. package/src/progress.js +1 -0
  84. package/src/rect.d.ts +5 -0
  85. package/src/rect.js +16 -0
  86. package/src/resource.d.ts +12 -0
  87. package/src/resource.js +28 -0
  88. package/src/schedule.d.ts +10 -0
  89. package/src/schedule.js +33 -0
  90. package/src/set.d.ts +2 -0
  91. package/src/set.js +2 -0
  92. package/src/signal.d.ts +37 -0
  93. package/src/signal.js +89 -0
  94. package/src/stream.d.ts +6 -0
  95. package/src/stream.js +26 -0
  96. package/src/string.d.ts +8 -0
  97. package/src/string.js +29 -0
  98. package/src/struct.d.ts +42 -0
  99. package/src/struct.js +58 -0
  100. package/src/tree.d.ts +11 -0
  101. package/src/tree.js +25 -0
  102. package/src/treemap.d.ts +13 -0
  103. package/src/treemap.js +71 -0
  104. package/src/typedarray.d.ts +31 -0
  105. package/src/typedarray.js +39 -0
  106. package/src/types.d.ts +63 -0
  107. package/src/types.js +1 -0
  108. package/src/utils.d.ts +4 -0
  109. package/src/utils.js +30 -0
  110. package/src/weak.d.ts +2 -0
  111. package/src/weak.js +5 -0
  112. package/stream.d.ts +1 -1
  113. package/stream.js +2 -2
  114. package/string.d.ts +2 -1
  115. package/string.js +3 -2
  116. package/struct.d.ts +2 -2
  117. package/struct.js +2 -2
  118. package/tree.d.ts +3 -3
  119. package/tree.js +8 -10
  120. package/treemap.d.ts +12 -12
  121. package/treemap.js +62 -59
  122. package/typedarray.d.ts +1 -1
  123. package/typedarray.js +3 -3
  124. package/types.d.ts +3 -7
  125. package/utils.d.ts +1 -1
  126. package/utils.js +1 -1
  127. package/weak.d.ts +2 -2
  128. package/weak.js +1 -1
package/src/set.js ADDED
@@ -0,0 +1,2 @@
1
+ export const add = (xs, x) => (xs.add(x), () => xs.delete(x));
2
+ export const isEqual = (a, b) => a.size == b.size && a.isSubsetOf(b) && b.isSubsetOf(a);
@@ -0,0 +1,37 @@
1
+ import type { Fn, FnV, Fns, Pred, Reactive, RecordOf, Structure } from "./types.js";
2
+ export type Signal<T> = Fn<T> & {
3
+ on: Reactive<T>;
4
+ };
5
+ export declare const create: <T>(f: Fn<T>, on: Reactive<T>) => Signal<T>;
6
+ export declare const signal: <T>(fns?: Set<Fn<T>>) => Signal<T>;
7
+ export declare const map: <T, S>(source: Reactive<T>, f: Fn<T, S>) => Reactive<S>;
8
+ export declare const filter: <T>(source: Reactive<T>, p: Pred<T>) => Reactive<T>;
9
+ export declare const cache: <T>(source: Reactive<T>) => Reactive<T>;
10
+ export interface ValueLike<T> {
11
+ value: T;
12
+ on: Reactive<T>;
13
+ }
14
+ export interface Box<T, F extends RecordOf<FnV>> extends ValueLike<T> {
15
+ ops: F;
16
+ }
17
+ export interface Value<T> extends ValueLike<T> {
18
+ op: <F extends FnV>(f: Fn<T, F>) => F;
19
+ ops: <F extends RecordOf<FnV>>(f: Fn<T, F>) => F;
20
+ set: Fn<T>;
21
+ update(): void;
22
+ map<S>(f: Fn<T, S>): Reactive<S>;
23
+ box: <F extends RecordOf<FnV>>(f: Fn<T, F>) => Box<T, F>;
24
+ }
25
+ export declare const value: <T>(x: T, fs?: Set<Fn<T>>) => Value<T>;
26
+ export type Values<T extends RecordOf<any>> = {
27
+ [k in keyof T]: Value<T[k]>;
28
+ };
29
+ export declare const values: <T extends RecordOf<any>>(vals: T) => Values<T>;
30
+ type Unwrapped<T> = T extends ValueLike<infer U> ? U : {
31
+ [K in keyof T]: Unwrapped<T[K]>;
32
+ };
33
+ export declare const compose: <T extends Structure<ValueLike<any>>, S = Unwrapped<T>>(xs: T, transform?: Fn<Unwrapped<T>, S>) => Reactive<S>;
34
+ export declare const mux: <I extends RecordOf<any>, O extends RecordOf<any>>(init: Fn<Fns<O>, Fns<I>>) => Fns<I> & {
35
+ on: { [k in keyof O]: Reactive<O[k]>; };
36
+ };
37
+ export {};
package/src/signal.js ADDED
@@ -0,0 +1,89 @@
1
+ import { after, constantly, noop, bind, comp, forEach, filter as filter_, identity } from "./fn.js";
2
+ import { mapValues } from "./object.js";
3
+ import { isDefined, isFunction } from "./checks.js";
4
+ import { add } from "./set.js";
5
+ export const create = (f, on) => {
6
+ const g = f;
7
+ g.on = on;
8
+ return g;
9
+ };
10
+ export const signal = (fns = new Set()) => create((x) => fns.forEach(f => f(x)), bind(add, fns));
11
+ export const map = (source, f) => g => source(comp(f, g));
12
+ export const filter = (source, p) => f => source(filter_(p, f));
13
+ export const cache = (source) => {
14
+ let x;
15
+ source(y => x = y);
16
+ return f => {
17
+ if (isDefined(x))
18
+ f(x);
19
+ return source(f);
20
+ };
21
+ };
22
+ ;
23
+ ;
24
+ const isValueLike = (v) => Object.hasOwn(v, "value") && Object.hasOwn(v, "on") && isFunction(v.on);
25
+ export const value = (x, fs = new Set()) => {
26
+ const sig = signal(fs);
27
+ const notify = after(() => sig(x));
28
+ const op = (f) => notify(f(x));
29
+ const on = (f) => (f(x), sig.on(f));
30
+ const ops = (f) => mapValues(f(x), notify);
31
+ return {
32
+ get value() { return x; },
33
+ set value(y) { sig(x = y); },
34
+ op, on, ops,
35
+ set: op(constantly((y) => x = y)),
36
+ update: op(constantly(noop)),
37
+ map: bind(map, on),
38
+ box: (f) => ({
39
+ on,
40
+ get value() { return x; },
41
+ ops: ops(f),
42
+ })
43
+ };
44
+ };
45
+ export const values = (vals) => mapValues(vals, v => value(v));
46
+ export const compose = (xs, transform = identity) => f => {
47
+ const collect = (vs) => {
48
+ if (isValueLike(vs)) {
49
+ return vs.value;
50
+ }
51
+ else if (Array.isArray(vs)) {
52
+ return vs.map(collect);
53
+ }
54
+ return Object.fromEntries(Object.entries(vs).map(([k, v]) => [k, collect(v)]));
55
+ };
56
+ const notify = () => f(transform(collect(xs)));
57
+ let ready = false;
58
+ const sub = (vs) => {
59
+ if (isValueLike(vs)) {
60
+ return vs.on(() => { if (ready)
61
+ notify(); });
62
+ }
63
+ else if (Array.isArray(vs)) {
64
+ return forEach(...vs.map(sub));
65
+ }
66
+ return forEach(...Object.values(vs).map(sub));
67
+ };
68
+ const off = sub(xs);
69
+ ready = true;
70
+ notify();
71
+ return off;
72
+ };
73
+ export const mux = (init) => {
74
+ const sigs = {};
75
+ const ins = init(new Proxy({}, {
76
+ get: (_, k) => (x) => {
77
+ const f = sigs[k];
78
+ if (isDefined(f))
79
+ f(x);
80
+ }
81
+ }));
82
+ ins.on = new Proxy({}, {
83
+ get: (_, k) => f => {
84
+ const sig = sigs[k] ??= signal();
85
+ return sig.on(f);
86
+ }
87
+ });
88
+ return ins;
89
+ };
@@ -0,0 +1,6 @@
1
+ import type { Fn } from "./types.js";
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/src/stream.js ADDED
@@ -0,0 +1,26 @@
1
+ import { push } from "./array.js";
2
+ import { reduceA } from "./iterable.js";
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));
@@ -0,0 +1,8 @@
1
+ import type { Tuple } from "./types.js";
2
+ export declare const basename: (path: string) => string;
3
+ export declare const dirname: (path: string) => string;
4
+ export declare const splitext: (path: string) => Tuple<string, 2>;
5
+ export declare const objectURL: (data: Uint8Array<ArrayBuffer>, type: string) => string;
6
+ export declare const decode: (label?: string, opts?: TextDecoderOptions) => (x: Uint8Array, stream?: boolean) => string;
7
+ export declare const readLine: (delims?: Set<number>) => (data: Uint8Array, offset?: number) => string;
8
+ export declare const DATA_URL: RegExp;
package/src/string.js ADDED
@@ -0,0 +1,29 @@
1
+ import { EMPTY } from "./constants.js";
2
+ import { seek } from "./array.js";
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 splitext = (path) => {
10
+ const idx = path.lastIndexOf(".");
11
+ if (idx == -1)
12
+ return [path, ""];
13
+ return [path.slice(0, idx), path.slice(idx + 1)];
14
+ };
15
+ export const objectURL = (data, type) => URL.createObjectURL(new Blob([data], { type }));
16
+ export const decode = (label = "utf-8", opts = {
17
+ fatal: false, ignoreBOM: false
18
+ }) => {
19
+ const decoder = new TextDecoder(label, opts);
20
+ return (x, stream = false) => decoder.decode(x, { stream });
21
+ };
22
+ export const readLine = (delims = new Set([0x0A])) => {
23
+ const dec = decode();
24
+ return (data, offset = 0) => {
25
+ const n = seek(data, delims, offset);
26
+ return n > 0 ? dec(data.subarray(offset, n + 1)) : EMPTY.STR;
27
+ };
28
+ };
29
+ export const DATA_URL = /^data:(?<mime>[\w/\-\+]+)?(;(?<params>[\w\-]+\=[^;,\s]+)*)?(;(?<encoding>base64))?,(?<data>.*)$/;
@@ -0,0 +1,42 @@
1
+ import type { TypedArray, Fn, NumberArray } from "./types.js";
2
+ import type { Constructor } from "./typedarray.js";
3
+ export interface Type {
4
+ size: number;
5
+ align: number;
6
+ }
7
+ export type Vec<T extends TypedArray, N extends number> = Type & {
8
+ length: N;
9
+ type: Constructor<T>;
10
+ };
11
+ export declare const u8: <N extends number = 1>(length?: N, align?: number) => Vec<Uint8Array<ArrayBufferLike>, N>;
12
+ export declare const u16: <N extends number = 1>(length?: N, align?: number) => Vec<Uint16Array<ArrayBufferLike>, N>;
13
+ export declare const u32: <N extends number = 1>(length?: N, align?: number) => Vec<Uint32Array<ArrayBufferLike>, N>;
14
+ export declare const u64: <N extends number = 1>(length?: N, align?: number) => Vec<BigUint64Array<ArrayBufferLike>, N>;
15
+ export declare const i8: <N extends number = 1>(length?: N, align?: number) => Vec<Int8Array<ArrayBufferLike>, N>;
16
+ export declare const i16: <N extends number = 1>(length?: N, align?: number) => Vec<Int16Array<ArrayBufferLike>, N>;
17
+ export declare const i32: <N extends number = 1>(length?: N, align?: number) => Vec<Int32Array<ArrayBufferLike>, N>;
18
+ export declare const i64: <N extends number = 1>(length?: N, align?: number) => Vec<BigInt64Array<ArrayBufferLike>, N>;
19
+ export declare const f16: <N extends number = 1>(length?: N, align?: number) => Vec<Float16Array<ArrayBufferLike>, N>;
20
+ export declare const f32: <N extends number = 1>(length?: N, align?: number) => Vec<Float32Array<ArrayBufferLike>, N>;
21
+ export declare const f64: <N extends number = 1>(length?: N, align?: number) => Vec<Float64Array<ArrayBufferLike>, N>;
22
+ export type Array<T extends Type> = Type & {
23
+ type: T;
24
+ length: number;
25
+ offset: Fn<number, number>;
26
+ };
27
+ export declare const isArray: (t: any) => t is Array<any>;
28
+ export declare const array: <T extends Type>(type: T, length: number, align?: number) => Array<T>;
29
+ type Field<T extends Type> = readonly [name: string, type: T, align?: number];
30
+ export type Struct<T extends ReadonlyArray<Field<any>>> = Type & {
31
+ fields: {
32
+ [K in T[number] as K[0]]: K[1];
33
+ };
34
+ offset(key: T[number][0]): number;
35
+ };
36
+ export declare const isStruct: (t: any) => t is Struct<any>;
37
+ export declare const struct: <T extends ReadonlyArray<Field<any>>>(fs: T, align?: number, offset?: number) => Struct<T>;
38
+ export type View<T extends Type> = T extends Vec<infer C, any> ? C : T extends Array<infer S> ? View<S>[] : T extends Struct<infer F> ? {
39
+ [K in F[number] as K[0]]: K[1] extends Vec<infer C, infer N> ? (N extends 1 ? (C extends NumberArray ? number : bigint) : C) : View<K[1]>;
40
+ } : never;
41
+ export declare const view: <T extends Vec<any, any> | Array<any> | Struct<any>>(t: T, buf?: ArrayBufferLike, offset?: number) => View<T>;
42
+ export {};
package/src/struct.js ADDED
@@ -0,0 +1,58 @@
1
+ import { align as _align } from "./math.js";
2
+ import { isBigIntArray, isNumberArray } from "./checks.js";
3
+ const vec = (type) => (length = 1, align = type.BYTES_PER_ELEMENT) => ({
4
+ type, align, length, size: type.BYTES_PER_ELEMENT * length,
5
+ });
6
+ export const u8 = vec(Uint8Array);
7
+ export const u16 = vec(Uint16Array);
8
+ export const u32 = vec(Uint32Array);
9
+ export const u64 = vec(BigUint64Array);
10
+ export const i8 = vec(Int8Array);
11
+ export const i16 = vec(Int16Array);
12
+ export const i32 = vec(Int32Array);
13
+ export const i64 = vec(BigInt64Array);
14
+ export const f16 = vec(Float16Array);
15
+ export const f32 = vec(Float32Array);
16
+ export const f64 = vec(Float64Array);
17
+ export const isArray = (t) => Object.hasOwn(t, "length") && Object.hasOwn(t, "offset");
18
+ export const array = (type, length, align = type.align) => {
19
+ const step = _align(type.size, align);
20
+ return ({
21
+ type, align, length,
22
+ size: step * length,
23
+ offset: i => i * step
24
+ });
25
+ };
26
+ export const isStruct = (t) => Object.hasOwn(t, "offset") && Object.hasOwn(t, "fields");
27
+ export const struct = (fs, align = 0, offset = 0) => {
28
+ const fields = {}, offsets = {};
29
+ for (const [name, type, align_ = type.align] of fs) {
30
+ align = Math.max(align, align_);
31
+ offset = _align(offset, align_);
32
+ fields[name] = type;
33
+ offsets[name] = offset;
34
+ offset += type.size;
35
+ }
36
+ return {
37
+ size: _align(offset, align),
38
+ align,
39
+ fields: fields,
40
+ offset: k => offsets[k]
41
+ };
42
+ };
43
+ const property = (value) => ({
44
+ enumerable: true,
45
+ ...((isNumberArray(value) || isBigIntArray(value)) && value.length == 1 ? {
46
+ get: () => value[0],
47
+ set: (x) => value[0] = x,
48
+ } : { value })
49
+ });
50
+ export const view = (t, buf = new ArrayBuffer(t.size), offset = 0) => {
51
+ if (isArray(t)) {
52
+ return Array.from({ length: t.length }, (_, i) => view(t.type, buf, offset + t.offset(i)));
53
+ }
54
+ else if (isStruct(t)) {
55
+ return Object.entries(t.fields).reduce((o, [name, type]) => Object.defineProperty(o, name, property(view(type, buf, offset + t.offset(name)))), {});
56
+ }
57
+ return new t.type(buf, offset, t.length);
58
+ };
package/src/tree.d.ts ADDED
@@ -0,0 +1,11 @@
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>(x: Node<S, T>, p?: TPred<Tree<S, T>, Node<S, T>>) => Node<S, T>[];
7
+ export declare const value: <S, T = S>(x: Node<S, T>, p?: TPred<Tree<S, T>, 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 zip: <S, T, U, V>(na: Node<S, T>[], nb: Node<U, V>[]) => Node<[S, U], [T, V]>[];
package/src/tree.js ADDED
@@ -0,0 +1,25 @@
1
+ import { identity } from './fn.js';
2
+ import { EMPTY } from './constants.js';
3
+ import { zip as zipI } from './iterable.js';
4
+ export const tree = (value, children = []) => [value, children];
5
+ export const isTree = (x) => Array.isArray(x) && x.length == 2 && Array.isArray(x[1]);
6
+ export const children = (x, p = isTree) => p(x) ? x[1] : EMPTY.LIST;
7
+ export const value = (x, p = isTree) => p(x) ? x[0] : x;
8
+ export const transform = (node, leaf, p = isTree) => {
9
+ const f = (c) => (x) => p(x) ? node(x, f, c) : leaf(x, c);
10
+ return f;
11
+ };
12
+ export const map = (parent, child, update = identity, p = isTree) => transform((x, f, c) => tree(parent(x[0], c), x[1].map(f(update(c, x[0])))), child, p);
13
+ export const filter = (ps, update = identity, p = isTree) => transform((x, f, c) => tree(x[0], x[1].filter(x => ps(x, c)).map(f(update(c, x[0])))), identity, p);
14
+ export const zip = (na, nb) => {
15
+ const res = [];
16
+ for (const [a, b] of zipI(Iterator.from(na), Iterator.from(nb))) {
17
+ if (!isTree(a) && !isTree(a))
18
+ res.push([value(a), value(b)]);
19
+ else if ((isTree(a) && isTree(a)))
20
+ res.push([[value(a), value(b)], zip(children(a), children(b))]);
21
+ else
22
+ throw new Error("[tree] a and b should be both tree or node");
23
+ }
24
+ return res;
25
+ };
@@ -0,0 +1,13 @@
1
+ import type { Maybe } from "./types.js";
2
+ export interface Treemap<T = number> {
3
+ set(node: T, parent?: T): Treemap<T>;
4
+ delete(key: T): void;
5
+ parent(key: T): Maybe<T>;
6
+ size: number;
7
+ children(key: T): T[];
8
+ roots(): IteratorObject<T>;
9
+ ancestors(node: T): IteratorObject<T>;
10
+ dfs(root: T): IteratorObject<T>;
11
+ bfs(): IteratorObject<T>;
12
+ }
13
+ export declare const treemap: <T = number>() => Treemap<T>;
package/src/treemap.js ADDED
@@ -0,0 +1,71 @@
1
+ import { before } from "./fn.js";
2
+ import { isDefined } from "./checks.js";
3
+ import { EMPTY } from "./constants.js";
4
+ export const treemap = () => {
5
+ const nodes = new Set();
6
+ const parents = new Map();
7
+ const children = new Map();
8
+ let changed = false;
9
+ const update = () => {
10
+ const hasChanged = changed;
11
+ if (hasChanged) {
12
+ children.clear();
13
+ for (const k of nodes) {
14
+ const p = parents.get(k);
15
+ if (isDefined(p)) {
16
+ if (!children.has(p))
17
+ children.set(p, []);
18
+ children.get(p).push(k);
19
+ }
20
+ }
21
+ changed = false;
22
+ }
23
+ return hasChanged;
24
+ };
25
+ const updated = before(update);
26
+ const getChildren = updated((key) => children.get(key) ?? EMPTY.LIST);
27
+ const parent = updated((key) => parents.get(key));
28
+ const roots = () => nodes.values().filter(k => !parents.has(k));
29
+ return {
30
+ set(node, parent) {
31
+ nodes.add(node);
32
+ if (isDefined(parent)) {
33
+ nodes.add(parent);
34
+ parents.set(node, parent);
35
+ }
36
+ changed = true;
37
+ return this;
38
+ },
39
+ delete(key) {
40
+ nodes.delete(key);
41
+ parents.delete(key);
42
+ changed = true;
43
+ },
44
+ get size() {
45
+ update();
46
+ return nodes.size;
47
+ },
48
+ parent,
49
+ children: getChildren,
50
+ roots,
51
+ ancestors: updated(function* (node) {
52
+ for (let cur = node; isDefined(cur); cur = parent(cur))
53
+ yield cur;
54
+ }),
55
+ dfs: updated(function* (root) {
56
+ const stack = [root];
57
+ for (let node; stack.length > 0;) {
58
+ yield node = stack.pop();
59
+ const items = getChildren(node);
60
+ for (let i = items.length - 1; i >= 0; i--)
61
+ stack.push(items[i]);
62
+ }
63
+ }),
64
+ bfs: updated(function* (queue = [...roots()]) {
65
+ for (let node; queue.length > 0;) {
66
+ yield node = queue.shift();
67
+ queue.push(...getChildren(node));
68
+ }
69
+ })
70
+ };
71
+ };
@@ -0,0 +1,31 @@
1
+ import type { FnV, TypedArray, NumberArray, BufferType, Number } from "./types.js";
2
+ export interface Constructor<T extends TypedArray> {
3
+ new (length: number): T;
4
+ new (buffer: BufferType<T> | ArrayBufferLike, byteOffset?: number, length?: number): T;
5
+ readonly BYTES_PER_ELEMENT: number;
6
+ of(...items: Number<T>[]): T;
7
+ from(arrayLike: ArrayLike<Number<T>>): T;
8
+ }
9
+ export type View<T extends TypedArray> = FnV<[BufferType<T>?, number?], T>;
10
+ export declare const view: <T extends TypedArray>(type: Constructor<T>, length: number) => View<T>;
11
+ export declare const u8: (length: number) => View<Uint8Array<ArrayBufferLike>>;
12
+ export declare const u16: (length: number) => View<Uint16Array<ArrayBufferLike>>;
13
+ export declare const u32: (length: number) => View<Uint32Array<ArrayBufferLike>>;
14
+ export declare const u64: (length: number) => View<BigUint64Array<ArrayBufferLike>>;
15
+ export declare const i8: (length: number) => View<Int8Array<ArrayBufferLike>>;
16
+ export declare const i16: (length: number) => View<Int16Array<ArrayBufferLike>>;
17
+ export declare const i32: (length: number) => View<Int32Array<ArrayBufferLike>>;
18
+ export declare const i64: (length: number) => View<BigInt64Array<ArrayBufferLike>>;
19
+ export declare const f16: (length: number) => View<Float16Array<ArrayBufferLike>>;
20
+ export declare const f32: (length: number) => View<Float32Array<ArrayBufferLike>>;
21
+ export declare const f64: (length: number) => View<Float64Array<ArrayBufferLike>>;
22
+ export declare const UintArray: (n: number) => Uint8ArrayConstructor | Uint16ArrayConstructor | Uint32ArrayConstructor;
23
+ export declare const ctor: <T extends TypedArray>(x: T) => Constructor<T>;
24
+ export declare const emptyLike: <T extends TypedArray>(x: T) => T;
25
+ export declare const set: <T extends TypedArray>(xs: T, x: ArrayLike<Number<T>> | T, i: number) => T;
26
+ export declare const concat: <T extends TypedArray>(chunks: T[]) => T;
27
+ export declare const iter: (size: number, stride?: number) => <T extends TypedArray>(data: T) => Generator<T>;
28
+ export declare const tile: (n: number) => (out: TypedArray, x: TypedArray) => TypedArray;
29
+ export declare const tileEvery: (m: number, n: number) => <T extends TypedArray>(xs: T, out?: T) => T;
30
+ export declare const strided: <T extends TypedArray>(data: T, size: number, stride?: number, out?: T) => T;
31
+ export declare const toFixed: (n: number, sep?: string) => (xs: NumberArray) => string;
@@ -0,0 +1,39 @@
1
+ import { bind } from "./fn.js";
2
+ import { zmap, map as mapI, reduce } from "./iterable.js";
3
+ import { push } from "./array.js";
4
+ export const view = (type, length) => (buf = new ArrayBuffer(type.BYTES_PER_ELEMENT * length), offset = 0) => new type(buf, offset, length);
5
+ export const u8 = bind((view), Uint8Array);
6
+ export const u16 = bind((view), Uint16Array);
7
+ export const u32 = bind((view), Uint32Array);
8
+ export const u64 = bind((view), BigUint64Array);
9
+ export const i8 = bind((view), Int8Array);
10
+ export const i16 = bind((view), Int16Array);
11
+ export const i32 = bind((view), Int32Array);
12
+ export const i64 = bind((view), BigInt64Array);
13
+ export const f16 = bind((view), Float16Array);
14
+ export const f32 = bind((view), Float32Array);
15
+ export const f64 = bind((view), Float64Array);
16
+ export const UintArray = (n) => n < 256 ? Uint8Array : n < 65536 ? Uint16Array : Uint32Array;
17
+ export const ctor = (x) => x.constructor;
18
+ export const emptyLike = (x) => new (ctor(x))(x.length);
19
+ export const set = (xs, x, i) => (xs.set(x, i), xs);
20
+ export const concat = (chunks) => {
21
+ const out = new (ctor(chunks[0]))(chunks.reduce((a, x) => a + x.length, 0));
22
+ chunks.reduce((offset, chunk) => (out.set(chunk, offset), offset + chunk.length), 0);
23
+ return out;
24
+ };
25
+ export const iter = (size, stride = size) => function* (data) {
26
+ const C = ctor(data);
27
+ for (let i = 0, n = data.length; i < n - size + 1; i += stride) {
28
+ const offset = data.byteOffset + i * C.BYTES_PER_ELEMENT;
29
+ yield new C(data.buffer, offset, size);
30
+ }
31
+ };
32
+ export const tile = (n) => (out, x) => {
33
+ for (let i = 0; i < n; i++)
34
+ set(out, x, i * x.length);
35
+ return out;
36
+ };
37
+ export const tileEvery = (m, n) => (xs, out = new (ctor(xs))(xs.length * n)) => (zmap(tile(n))(iter(m * n)(out), iter(m)(xs)), out);
38
+ export const strided = (data, size, stride = size, out = new (ctor(data))(data.length / size * stride)) => (iter(size)(data).forEach((p, i) => set(out, p, i * stride)), out);
39
+ export const toFixed = (n, sep = ',') => (xs) => reduce((push), [])(mapI(x => x.toFixed(n))(Iterator.from(xs))).join(sep);
package/src/types.d.ts ADDED
@@ -0,0 +1,63 @@
1
+ export interface RecordOf<T> {
2
+ [id: PropertyKey]: T;
3
+ }
4
+ export type ValueOf<T> = T[keyof T];
5
+ export type Structure<T> = T | readonly Structure<T>[] | RecordOf<Structure<T>>;
6
+ export type Optional<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>> & Partial<Pick<T, K>>;
7
+ export type Tuple<T, N extends number, R extends T[] = []> = R['length'] extends N ? R : Tuple<T, N, [T, ...R]>;
8
+ export type Elements<A extends readonly unknown[]> = A extends readonly (infer T)[] ? T : never;
9
+ export type MaybeFirst<T extends unknown[], S = void> = T extends {
10
+ length: 0;
11
+ } ? S : T[0];
12
+ export type FnV<T extends any[] = any[], R = any> = (...x: T) => R;
13
+ export type Fn<T = any, R = any> = FnV<[T], R>;
14
+ export type FnP<T = any, R = any> = (x: T) => Promise<R>;
15
+ export type Fns<T> = {
16
+ [k in keyof T]: Fn<T[k]>;
17
+ };
18
+ export type FnF = <F extends FnV>(f: F) => (...xs: Parameters<F>) => ReturnType<F>;
19
+ export type Dispose = Fn<void>;
20
+ export type Reactive<T = unknown, R = any> = Fn<Fn<T, R>, Dispose>;
21
+ export type Constantly<T> = () => T;
22
+ export type FirstParam<F extends FnV> = MaybeFirst<Parameters<F>>;
23
+ export type MaybePromise<T = unknown> = T | PromiseLike<T>;
24
+ export type Last<T extends any[]> = T extends [...any, infer Rest] ? Rest : never;
25
+ export type Tail<T extends any[]> = T extends [any, ...(infer Rest)] ? Rest : never;
26
+ export type Push<T extends any[], V> = [...T, V];
27
+ export type Pop<T extends any[]> = T extends [...infer head, any] ? head : never;
28
+ export type MinusOne<T extends number, A extends any[] = []> = A['length'] extends T ? Pop<A>['length'] : MinusOne<T, [...A, 0]>;
29
+ export type Take<N extends number, T extends any[], R extends any[] = []> = R['length'] extends N ? R : Take<N, Tail<T>, [...R, T[0]]>;
30
+ export type Skip<N extends number, T extends any[]> = N extends 0 ? T : Skip<MinusOne<N>, Tail<T>>;
31
+ export type Range<N extends number, Acc extends number[] = []> = Acc['length'] extends N ? Acc[number] : Range<N, [...Acc, Acc['length']]>;
32
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
33
+ export type LastOf<T> = UnionToIntersection<T extends any ? (x: T) => void : never> extends (x: infer L) => void ? L : never;
34
+ export type UnionToTuple<T> = [T] extends [never] ? [] : Push<UnionToTuple<Exclude<T, LastOf<T>>>, LastOf<T>>;
35
+ export type Entry<K extends PropertyKey, V> = [K, V];
36
+ export type Entries<T> = {
37
+ [K in keyof T]: Entry<K, T[K]>;
38
+ }[keyof T];
39
+ export type EntriesTuple<T, K extends UnionToTuple<keyof T> = UnionToTuple<keyof T>> = {
40
+ [I in keyof K]: K[I] extends keyof T ? [K[I], T[K[I]]] : never;
41
+ };
42
+ export type UintArray<T extends ArrayBufferLike = ArrayBufferLike> = Uint8Array<T> | Uint16Array<T> | Uint32Array<T>;
43
+ export type IntArray<T extends ArrayBufferLike = ArrayBufferLike> = Int8Array<T> | Int16Array<T> | Int32Array<T>;
44
+ export type FloatArray<T extends ArrayBufferLike = ArrayBufferLike> = Float16Array<T> | Float32Array<T> | Float64Array<T>;
45
+ export type BigIntArray<T extends ArrayBufferLike = ArrayBufferLike> = BigUint64Array<T> | BigInt64Array<T>;
46
+ export type NumberArray<T extends ArrayBufferLike = ArrayBufferLike> = UintArray<T> | IntArray<T> | FloatArray<T>;
47
+ export type TypedArray<T extends ArrayBufferLike = ArrayBufferLike> = NumberArray | BigIntArray<T>;
48
+ export type Number<T extends TypedArray> = T extends NumberArray ? number : bigint;
49
+ export type BufferType<T extends TypedArray> = T extends TypedArray<infer S> ? S : never;
50
+ export type Eq<A, B = A> = FnV<[A, B], boolean>;
51
+ export type Pred<T> = Fn<T, boolean>;
52
+ export type PredV<T extends any[]> = FnV<T, boolean>;
53
+ export type TPred<T extends S, S = any> = (x: S) => x is T;
54
+ export type Maybe<T> = T | undefined;
55
+ export type Indexed<T> = [number, T];
56
+ export type Required<T, K extends keyof T> = T & {
57
+ [P in K]-?: T[P];
58
+ };
59
+ export type Partials<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
60
+ export type KeyMap<T extends string> = {
61
+ [K in T]: Extract<K, T>;
62
+ };
63
+ export {};
package/src/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
package/src/utils.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ import type { Tuple } from "./types.js";
2
+ export declare function toposort(nodes: number[]): Generator<number | undefined, void, unknown>;
3
+ export declare const hex2rgb: (hex: string) => number[];
4
+ export declare const rgb2hex: (rgb: Tuple<number, 3>) => string;
package/src/utils.js ADDED
@@ -0,0 +1,30 @@
1
+ import { assert } from "./checks.js";
2
+ export function* toposort(nodes) {
3
+ const n = nodes.length;
4
+ const queue = [], children = new Map();
5
+ nodes.forEach((p, i) => {
6
+ if (p < 0)
7
+ queue.push(i);
8
+ else {
9
+ assert(p < n, `[toposort] Invalid parent: ${p}`);
10
+ if (!children.has(p))
11
+ children.set(p, []);
12
+ children.get(p).push(i);
13
+ }
14
+ });
15
+ while (queue.length > 0) {
16
+ const p = queue.shift();
17
+ yield p;
18
+ if (children.has(p)) {
19
+ queue.push(...children.get(p));
20
+ children.delete(p);
21
+ }
22
+ }
23
+ }
24
+ export const hex2rgb = (hex) => {
25
+ const r = parseInt(hex.slice(1, 3), 16);
26
+ const g = parseInt(hex.slice(3, 5), 16);
27
+ const b = parseInt(hex.slice(5, 7), 16);
28
+ return [r, g, b];
29
+ };
30
+ export const rgb2hex = (rgb) => "#" + rgb.map(x => Math.round(x).toString(16).padStart(2, '0')).join("");
package/src/weak.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import type { Fn, Maybe } from "./types.js";
2
+ export declare const deref: <T extends WeakKey, F extends Fn<T>>(r: WeakRef<T>, f: F) => Maybe<ReturnType<F>>;
package/src/weak.js ADDED
@@ -0,0 +1,5 @@
1
+ import { isDefined } from "./checks.js";
2
+ export const deref = (r, f) => {
3
+ const x = r.deref();
4
+ return isDefined(x) ? f(x) : undefined;
5
+ };
package/stream.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Fn } from "./types";
1
+ import type { Fn } from "./types.js";
2
2
  export declare const readable: <T>(x: T) => ReadableStream<any>;
3
3
  export declare function iterate<T>(rs: ReadableStream<T>): AsyncGenerator<Awaited<T>, void, unknown>;
4
4
  export declare const map: <T, S>(f: Fn<T, S>) => TransformStream<T, S>;
package/stream.js CHANGED
@@ -1,5 +1,5 @@
1
- import { push } from "./array";
2
- import { reduceA } from "./iterable";
1
+ import { push } from "./array.js";
2
+ import { reduceA } from "./iterable.js";
3
3
  export const readable = (x) => new ReadableStream({
4
4
  start: c => (c.enqueue(x), c.close())
5
5
  });
package/string.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import type { Tuple } from "./types";
1
+ import type { Tuple } from "./types.js";
2
2
  export declare const basename: (path: string) => string;
3
3
  export declare const dirname: (path: string) => string;
4
4
  export declare const splitext: (path: string) => Tuple<string, 2>;
5
5
  export declare const objectURL: (data: Uint8Array<ArrayBuffer>, type: string) => 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
+ export declare const DATA_URL: RegExp;