@cgtk/std 0.0.193 → 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 (121) 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 +1 -1
  6. package/async.js +2 -2
  7. package/basen.js +1 -1
  8. package/buffer.d.ts +1 -1
  9. package/buffer.js +1 -1
  10. package/checks.d.ts +1 -1
  11. package/checks.js +2 -2
  12. package/dom.d.ts +1 -1
  13. package/dom.js +3 -3
  14. package/fn.d.ts +1 -1
  15. package/fn.js +1 -1
  16. package/http.js +2 -2
  17. package/iterable.d.ts +1 -1
  18. package/iterable.js +3 -3
  19. package/map.d.ts +1 -1
  20. package/map.js +2 -2
  21. package/math.js +1 -1
  22. package/npy.d.ts +1 -1
  23. package/number.js +1 -1
  24. package/package.json +2 -2
  25. package/port.d.ts +1 -1
  26. package/port.js +4 -4
  27. package/progress.d.ts +1 -1
  28. package/rect.d.ts +1 -1
  29. package/rect.js +1 -1
  30. package/resource.d.ts +1 -1
  31. package/resource.js +2 -2
  32. package/schedule.d.ts +1 -1
  33. package/schedule.js +2 -2
  34. package/signal.d.ts +1 -1
  35. package/signal.js +4 -4
  36. package/src/array.d.ts +14 -0
  37. package/src/array.js +21 -0
  38. package/src/assign.d.ts +8 -0
  39. package/src/assign.js +26 -0
  40. package/src/async.d.ts +8 -0
  41. package/src/async.js +31 -0
  42. package/src/base64.d.ts +1 -0
  43. package/src/base64.js +7 -0
  44. package/src/basen.d.ts +12 -0
  45. package/src/basen.js +31 -0
  46. package/src/buffer.d.ts +14 -0
  47. package/src/buffer.js +54 -0
  48. package/src/checks.d.ts +29 -0
  49. package/src/checks.js +44 -0
  50. package/src/constants.d.ts +5 -0
  51. package/src/constants.js +1 -0
  52. package/src/dom.d.ts +50 -0
  53. package/src/dom.js +36 -0
  54. package/src/fn.d.ts +33 -0
  55. package/src/fn.js +61 -0
  56. package/src/http.d.ts +9 -0
  57. package/src/http.js +33 -0
  58. package/src/index.d.ts +1 -0
  59. package/src/index.js +1 -0
  60. package/src/iterable.d.ts +43 -0
  61. package/src/iterable.js +158 -0
  62. package/src/json.d.ts +1 -0
  63. package/src/json.js +1 -0
  64. package/src/map.d.ts +12 -0
  65. package/src/map.js +35 -0
  66. package/src/math.d.ts +34 -0
  67. package/src/math.js +43 -0
  68. package/src/npy.d.ts +10 -0
  69. package/src/npy.js +29 -0
  70. package/src/number.d.ts +4 -0
  71. package/src/number.js +13 -0
  72. package/src/object.d.ts +15 -0
  73. package/src/object.js +13 -0
  74. package/src/port.d.ts +30 -0
  75. package/src/port.js +56 -0
  76. package/src/progress.d.ts +6 -0
  77. package/src/progress.js +1 -0
  78. package/src/rect.d.ts +5 -0
  79. package/src/rect.js +16 -0
  80. package/src/resource.d.ts +12 -0
  81. package/src/resource.js +28 -0
  82. package/src/schedule.d.ts +10 -0
  83. package/src/schedule.js +33 -0
  84. package/src/set.d.ts +2 -0
  85. package/src/set.js +2 -0
  86. package/src/signal.d.ts +37 -0
  87. package/src/signal.js +89 -0
  88. package/src/stream.d.ts +6 -0
  89. package/src/stream.js +26 -0
  90. package/src/string.d.ts +8 -0
  91. package/src/string.js +29 -0
  92. package/src/struct.d.ts +42 -0
  93. package/src/struct.js +58 -0
  94. package/src/tree.d.ts +11 -0
  95. package/src/tree.js +25 -0
  96. package/src/treemap.d.ts +13 -0
  97. package/src/treemap.js +71 -0
  98. package/src/typedarray.d.ts +31 -0
  99. package/src/typedarray.js +39 -0
  100. package/src/types.d.ts +63 -0
  101. package/src/types.js +1 -0
  102. package/src/utils.d.ts +4 -0
  103. package/src/utils.js +30 -0
  104. package/src/weak.d.ts +2 -0
  105. package/src/weak.js +5 -0
  106. package/stream.d.ts +1 -1
  107. package/stream.js +2 -2
  108. package/string.d.ts +1 -1
  109. package/string.js +2 -2
  110. package/struct.d.ts +2 -2
  111. package/struct.js +2 -2
  112. package/tree.d.ts +1 -1
  113. package/tree.js +3 -3
  114. package/treemap.d.ts +1 -1
  115. package/treemap.js +3 -3
  116. package/typedarray.d.ts +1 -1
  117. package/typedarray.js +3 -3
  118. package/utils.d.ts +1 -1
  119. package/utils.js +1 -1
  120. package/weak.d.ts +1 -1
  121. package/weak.js +1 -1
package/src/object.js ADDED
@@ -0,0 +1,13 @@
1
+ export const entries = (o) => Object.entries(o);
2
+ export const keys = (o) => Object.keys(o);
3
+ export const entry = (k, v) => [k, v];
4
+ export const fromEntries = (xs) => Object.fromEntries(xs);
5
+ export const mapEntries = (o, f) => fromEntries(entries(o).map(f));
6
+ export const mapValues = (o, f) => mapEntries(o, ([k, v]) => entry(k, f(v, k)));
7
+ export const pick = (obj, keys) => keys.reduce((a, k) => (a[k] = obj[k], a), {});
8
+ export const omit = (obj, keys) => pick(obj, Object.keys(obj).filter(k => !keys.includes(k)));
9
+ export const assoc = (a, [k, v]) => (a[k] = v, a);
10
+ export const merge = (f) => (x, y) => {
11
+ const keys = [...new Set(Object.keys(x).concat(Object.keys(y))).keys()];
12
+ return keys.reduce((a, k) => (a[k] = f(x[k], y[k]), a), {});
13
+ };
package/src/port.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import type { Dispose, Fn, Fns, FnV, RecordOf, MaybePromise, Reactive } from "./types.js";
2
+ export interface Message<K, V> {
3
+ type: K;
4
+ payload: V;
5
+ }
6
+ export type Port = {
7
+ postMessage(message: any, options?: StructuredSerializeOptions): void;
8
+ };
9
+ export declare const onMessages: <S extends RecordOf<any>, T = Worker>(target: MessageEventTarget<T>, fs: Fns<S>) => Dispose;
10
+ export declare const onMessage: <K extends string, S, T = Worker>(target: MessageEventTarget<T>, name: K, f: Fn<S>) => Dispose;
11
+ export declare const messageSources: <T extends RecordOf<any>, S = Worker>(worker: MessageEventTarget<S>) => { [K in keyof T]: Reactive<T[K]>; };
12
+ export declare const postMessages: <T extends RecordOf<any>>(port: Port) => { [k in keyof T]: FnV<[T[k], (StructuredSerializeOptions | undefined)?]>; };
13
+ export interface Request {
14
+ id: number;
15
+ name: PropertyKey;
16
+ args: any;
17
+ }
18
+ export interface Response {
19
+ id: number;
20
+ result: any;
21
+ }
22
+ interface TransferableFnV<T extends any[], R> {
23
+ (...args: T): R;
24
+ transfer(ts?: Transferable[]): FnV<T, R>;
25
+ }
26
+ export declare const client: <S extends RecordOf<any>, T = Worker>(target: Port & MessageEventTarget<T>) => { [k in keyof S]: TransferableFnV<Parameters<S[k]>, Promise<ReturnType<S[k]>>>; };
27
+ export declare const server: <S extends RecordOf<any>, T = Worker>(target: Port & MessageEventTarget<T>) => { [k in keyof S]: Fn<FnV<Parameters<S[k]>, MaybePromise<ReturnType<S[k]>>>, Dispose>; };
28
+ export declare const startClient: (worker: Worker, f: Fn<Worker, Dispose | void>) => Promise<Dispose>;
29
+ export declare const startServer: (worker: Worker, f: Fn<Worker, MaybePromise<Dispose>>) => Promise<Dispose>;
30
+ export {};
package/src/port.js ADDED
@@ -0,0 +1,56 @@
1
+ import { forEach, noop, bind } from "./fn.js";
2
+ import { isDefined } from "./checks.js";
3
+ import { on } from "./dom.js";
4
+ import { promise } from "./async.js";
5
+ ;
6
+ export const onMessages = (target, fs) => on(target, "message", ({ data: { type, payload } }) => (type in fs) && fs[type](payload));
7
+ export const onMessage = (target, name, f) => on(target, "message", ({ data: { type, payload } }) => type == name && f(payload));
8
+ export const messageSources = (worker) => new Proxy({}, {
9
+ get: (_, k) => bind((onMessage), worker, k)
10
+ });
11
+ export const postMessages = (port) => new Proxy({}, {
12
+ get: (_, type) => (payload, options) => port.postMessage({ type, payload }, options)
13
+ });
14
+ export const client = (target) => {
15
+ const fns = new Map();
16
+ onMessage(target, "rpc", ({ id, result }) => {
17
+ const f = fns.get(id);
18
+ if (isDefined(f))
19
+ f(result), fns.delete(id);
20
+ });
21
+ const { rpc } = postMessages(target);
22
+ let _id = 0;
23
+ return new Proxy({}, {
24
+ get(_, name) {
25
+ const g = (transfer) => (...args) => {
26
+ const id = _id++;
27
+ rpc({ id, name, args }, { transfer });
28
+ return new Promise(resolve => fns.set(id, resolve));
29
+ };
30
+ const f = ((...args) => g()(...args));
31
+ f.transfer = g;
32
+ return f;
33
+ }
34
+ });
35
+ };
36
+ export const server = (target) => {
37
+ const fns = new Map();
38
+ const { rpc } = postMessages(target);
39
+ onMessage(target, "rpc", async ({ id, name, args }) => {
40
+ const f = fns.get(name);
41
+ if (isDefined(f))
42
+ rpc({ id, result: await promise(f(...args)) });
43
+ });
44
+ return new Proxy({}, {
45
+ get: (_, k) => (f) => (fns.set(k, f), () => fns.delete(k))
46
+ });
47
+ };
48
+ export const startClient = async (worker, f) => {
49
+ const cli = client(worker);
50
+ await cli.start();
51
+ return forEach(f(worker) ?? noop, () => cli.stop().then(() => worker.terminate()));
52
+ };
53
+ export const startServer = async (worker, f) => {
54
+ const ser = server(worker);
55
+ return ser.start(async () => { ser.stop(await promise(f(worker))); });
56
+ };
@@ -0,0 +1,6 @@
1
+ import type { Fn } from './types.js';
2
+ export type Progress = {
3
+ begin: Fn<void>;
4
+ progress: Fn<number>;
5
+ end: Fn<void>;
6
+ };
@@ -0,0 +1 @@
1
+ export {};
package/src/rect.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Tuple } from "./types.js";
2
+ export type Rect = Tuple<number, 4>;
3
+ export declare const rect: (x: number, y: number, w: number, h: number) => Rect;
4
+ export declare const vertical: (ratio: number[]) => (i: number) => ([x, _, w, h]: Rect) => Rect;
5
+ export declare const horizontal: (ratio: number[]) => (i: number) => ([_, y, w, h]: Rect) => Rect;
package/src/rect.js ADDED
@@ -0,0 +1,16 @@
1
+ import { add } from "./number.js";
2
+ export const rect = (x, y, w, h) => [x, y, w, h];
3
+ export const vertical = (ratio) => {
4
+ const tot = ratio.reduce(add, 0);
5
+ const cum = [0];
6
+ ratio.forEach(x => cum.push(x / tot + cum[cum.length - 1]));
7
+ cum.pop();
8
+ return (i) => ([x, _, w, h]) => [x, cum[i] * h, w, ratio[i] / tot * h];
9
+ };
10
+ export const horizontal = (ratio) => {
11
+ const tot = ratio.reduce(add, 0);
12
+ const cum = [0];
13
+ ratio.forEach(x => cum.push(x / tot + cum[cum.length - 1]));
14
+ cum.pop();
15
+ return (i) => ([_, y, w, h]) => [cum[i] * w, y, ratio[i] / tot * w, h];
16
+ };
@@ -0,0 +1,12 @@
1
+ import type { Fn, Dispose, Structure, Reactive } from "./types.js";
2
+ export type Resource<T> = Reactive<T, Dispose | void> & {
3
+ value: T;
4
+ dispose: Dispose;
5
+ map<S>(f: Fn<T, S>): Resource<S>;
6
+ };
7
+ export declare const resource: <T>(value: T, dispose?: Dispose) => Resource<T>;
8
+ type Unwrapped<T> = T extends Resource<infer U> ? U : {
9
+ [K in keyof T]: Unwrapped<T[K]>;
10
+ };
11
+ export declare const compose: <R extends Structure<Resource<any>>>(rs: R) => Resource<Unwrapped<R>>;
12
+ export {};
@@ -0,0 +1,28 @@
1
+ import { forEach, noop } from "./fn.js";
2
+ import { isFunction } from "./checks.js";
3
+ export const resource = (value, dispose = noop) => {
4
+ const res = ((f) => forEach(f(value) ?? noop, dispose));
5
+ res.value = value;
6
+ res.dispose = dispose;
7
+ res.map = (f) => resource(f(value), dispose);
8
+ return res;
9
+ };
10
+ const isResource = (r) => isFunction(r)
11
+ && Object.hasOwn(r, "value")
12
+ && Object.hasOwn(r, "dispose")
13
+ && isFunction(r["dispose"]);
14
+ export const compose = (rs) => {
15
+ const disposes = [];
16
+ const rec = (rs) => {
17
+ if (isResource(rs)) {
18
+ disposes.push(rs.dispose);
19
+ return rs.value;
20
+ }
21
+ else if (Array.isArray(rs)) {
22
+ return rs.map(rec);
23
+ }
24
+ return Object.fromEntries(Object.entries(rs).map(([k, v]) => [k, rec(v)]));
25
+ };
26
+ const value = rec(rs);
27
+ return resource(value, forEach(...disposes));
28
+ };
@@ -0,0 +1,10 @@
1
+ import type { Dispose, Fn, FnV, Reactive } from './types.js';
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) => 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
+ export declare const debounce: <T>(sched?: Reactive<T>) => Reactive<T>;
7
+ export declare const reset: <T>(sched?: Reactive<T>) => Reactive<T>;
8
+ export declare const repeatedly: <T>(f: Fn<void>, sched?: Reactive<T>) => () => any;
9
+ export declare const delayAfter: <F extends FnV<any>>(delta: number, n: number, f: F) => (x: any) => any;
10
+ export declare const micro: <F extends FnV>(f: F) => (...xs: Parameters<F>) => void;
@@ -0,0 +1,33 @@
1
+ import { isUndefined, isDefined, counted } from './checks.js';
2
+ import { comp, lazy, bind, apply, call, where, disposing, noop } from './fn.js';
3
+ export const raf = f => bind(cancelAnimationFrame, requestAnimationFrame(f));
4
+ export const timeout = (ms) => f => bind(clearTimeout, setTimeout(f, ms));
5
+ export const schedule = (s) => (f) => call(comp(apply(bind((lazy), f)), s));
6
+ export const idempotent = (s, d) => (f) => disposing()((...xs) => d(s(() => f(...xs))));
7
+ export const debounce = (sched = raf) => {
8
+ let cancel;
9
+ const stop = () => { if (isDefined(cancel))
10
+ cancel(), cancel = undefined; };
11
+ return (f) => {
12
+ if (isUndefined(cancel))
13
+ cancel = sched((x) => (cancel = undefined, f(x)));
14
+ return stop;
15
+ };
16
+ };
17
+ export const reset = (sched = raf) => {
18
+ let cancel = noop;
19
+ const stop = () => (cancel(), cancel = noop);
20
+ return (f) => {
21
+ stop();
22
+ cancel = sched(f);
23
+ return stop;
24
+ };
25
+ };
26
+ export const repeatedly = (f, sched = raf) => {
27
+ let cancel;
28
+ const g = () => (f(), (cancel = sched(g)));
29
+ cancel = sched(g);
30
+ return () => cancel();
31
+ };
32
+ export const delayAfter = (delta, n, f) => where(counted(n), f, schedule(reset(timeout(delta)))(f));
33
+ export const micro = (f) => (...xs) => queueMicrotask(() => f(...xs));
package/src/set.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const add: <T>(xs: Set<T>, x: T) => () => boolean;
2
+ export declare const isEqual: <T>(a: Set<T>, b: Set<T>) => boolean;
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>;