@cgtk/std 0.0.196 → 0.0.198

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 CHANGED
@@ -13,3 +13,8 @@ export declare const tuple: <T, N extends number>(...xs: T[] & {
13
13
  length: N;
14
14
  }) => Tuple<T, N>;
15
15
  export declare const seek: <T>(arr: ArrayLike<T>, vals: Set<T | number>, offset?: number) => number;
16
+ export declare const unique: <T>(vals: T[], compareFn?: (a: T, b: T) => number) => {
17
+ indices: number[];
18
+ inverse: number[];
19
+ };
20
+ export declare const argsort: <T>(arr: T[], compareFn?: (a: T, b: T) => number) => number[];
package/array.js CHANGED
@@ -20,3 +20,20 @@ export const seek = (arr, vals, offset = 0) => {
20
20
  return i;
21
21
  return -1;
22
22
  };
23
+ const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
24
+ export const unique = (vals, compareFn = compare) => {
25
+ const pairs = vals.map((x, i) => [x, i]);
26
+ pairs.sort((a, b) => compareFn(a[0], b[0]));
27
+ const indices = [], inverse = Array.from({ length: pairs.length });
28
+ let k = -1;
29
+ pairs.forEach((x, i) => {
30
+ if (i == 0 || x[0] != pairs[i - 1][0])
31
+ indices.push(x[1]), k++;
32
+ inverse[x[1]] = k;
33
+ });
34
+ return { indices, inverse };
35
+ };
36
+ export const argsort = (arr, compareFn = compare) => arr
37
+ .map((x, i) => [x, i])
38
+ .sort((a, b) => compareFn(a[0], b[0]))
39
+ .map(x => x[1]);
package/async.d.ts CHANGED
@@ -1,8 +1,7 @@
1
- import type { Fn, Lazy, Maybe, Dispose, MaybePromise } from "./types.js";
2
- export declare const timeout: (ms: number, signal?: AbortSignal) => Promise<unknown>;
1
+ import type { Lazy, Maybe, Dispose, MaybePromise, Promisified, AsyncDispose } from "./types.js";
2
+ export declare const RESOLVED: Promise<void>;
3
+ export declare const timeout: (ms: number, signal?: AbortSignal) => Promise<void>;
3
4
  export declare const delay: (ms: number, signal?: AbortSignal) => <T>(x: T) => Promise<T>;
4
5
  export declare const probing: <T>(p: Promise<T>) => Lazy<Maybe<T>>;
5
- export declare const resolved: <T>(p: Promise<T>) => (f: Fn<T>) => () => void;
6
- export declare const promise: <T>(x: MaybePromise<T>) => Promise<any>;
7
- export declare const then: <T>(p: Promise<T>) => <R>(f: Fn<T, R>) => Promise<R>;
8
- export declare const dispose: (p: Promise<Dispose>) => () => void;
6
+ export declare const promisify: <T>(x: MaybePromise<T>) => Promisified<T>;
7
+ export declare const dispose: (p: Promise<Dispose>) => AsyncDispose;
package/async.js CHANGED
@@ -1,5 +1,6 @@
1
- import { filterT, noop } from "./fn.js";
2
- import { isDefined } from "./checks.js";
1
+ import { noop, then } from "./fn.js";
2
+ import { isPromise } from "./checks.js";
3
+ export const RESOLVED = Promise.resolve();
3
4
  export const timeout = (ms, signal) => new Promise((resolve, reject) => {
4
5
  if (signal?.aborted)
5
6
  reject(signal.reason);
@@ -8,7 +9,7 @@ export const timeout = (ms, signal) => new Promise((resolve, reject) => {
8
9
  if (signal?.aborted)
9
10
  reject(signal.reason);
10
11
  else
11
- resolve(undefined);
12
+ resolve();
12
13
  }, ms);
13
14
  signal?.addEventListener("abort", () => (clearTimeout(t), reject(signal.reason)), { once: true });
14
15
  }
@@ -19,26 +20,10 @@ export const probing = (p) => {
19
20
  p.then(x => value = x);
20
21
  return () => value;
21
22
  };
22
- export const resolved = (p) => {
23
- const val = probing(p);
24
- return (f) => {
25
- const g = (filterT((isDefined), f));
26
- return () => g(val());
27
- };
28
- };
29
- export const promise = (x) => (x instanceof Promise) ? x : Promise.resolve(x);
30
- export const then = (p) => (f) => p.then(f);
23
+ export const promisify = (x) => (isPromise(x) ? x : Promise.resolve(x));
31
24
  export const dispose = (p) => {
32
- let dispose = noop;
33
- let disposed = false;
34
- p.then(d => {
35
- if (disposed)
36
- d();
37
- else
38
- dispose = d;
39
- });
40
- return () => {
41
- disposed = true;
42
- dispose();
43
- };
25
+ const { promise, resolve } = Promise.withResolvers();
26
+ let dispose = noop, disposed = false;
27
+ p.then(d => (dispose = then(d, resolve), disposed && dispose()));
28
+ return () => (disposed = true, dispose(), promise);
44
29
  };
package/checks.d.ts CHANGED
@@ -28,3 +28,6 @@ export declare const isEmpty: (x: {
28
28
  length: number;
29
29
  }) => boolean;
30
30
  export declare const counted: (n: number) => () => boolean;
31
+ export declare const isBitSet: (x: number, n: number) => boolean;
32
+ export declare const isPromise: <T = any>(x: any) => x is Promise<T>;
33
+ export declare const isPromiseLike: <T = any>(x: any) => x is PromiseLike<T>;
package/checks.js CHANGED
@@ -43,3 +43,6 @@ export const counted = (n) => {
43
43
  let m = 0;
44
44
  return () => m++ < n;
45
45
  };
46
+ export const isBitSet = (x, n) => (x & (1 << n)) !== 0;
47
+ export const isPromise = (x) => x instanceof Promise;
48
+ export const isPromiseLike = (x) => x instanceof Promise;
package/fn.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Fn, FnV, FnF, Pred, TPred, Last, Lazy, Dispose, Reactive } from "./types.js";
1
+ import type { Fn, FnV, FnF, Pred, Last, Lazy, Dispose, Reactive, Promisified, MaybePromise } from "./types.js";
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;
@@ -17,7 +17,6 @@ export declare const where: <T, U, V>(p: Pred<T>, f: Fn<T, U>, g: Fn<T, V>) => (
17
17
  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
- export declare const filterT: <T>(p: TPred<T>, f: Fn<T>) => <S>(x: S) => void;
21
20
  export declare const scan: <T, S>(f: FnV<[S, T], S>, a: S) => Fn<T, S>;
22
21
  export declare const memoize: <T extends any[], K, V>(f: FnV<T, V>, key?: FnV<T, K>, cache?: Map<K, V>) => (...xs: T) => NonNullable<V>;
23
22
  export declare const abortable: <T = any>(f: Fn<AbortSignal>) => (reason?: T) => void;
@@ -27,3 +26,5 @@ export declare const idemp: <F extends FnV<any[], Dispose | void>>(d: Fn<Dispose
27
26
  export declare const toggler: (f: Fn<void, Dispose>) => Fn<boolean, Dispose>;
28
27
  export declare const voidify: <F extends FnV>(f: F) => (...xs: Parameters<F>) => void;
29
28
  export declare const effectual: <T>(f: Reactive<T>, g: Fn<T>) => Dispose;
29
+ export declare const promisify: <F extends FnV>(f: F) => (...xs: Parameters<F>) => Promisified<ReturnType<F>>;
30
+ 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
@@ -1,4 +1,6 @@
1
1
  import { add } from "./set.js";
2
+ import * as Async from "./async.js";
3
+ import { isPromise } from "./checks.js";
2
4
  export const tee = f => x => (f(x), x);
3
5
  export const comp = (...fs) => (x) => fs.reduce((x, f) => f(x), x);
4
6
  export const pipe = (x, ...fs) => fs.reduce((x, f) => f(x), x);
@@ -22,8 +24,6 @@ export const after = (f) => g => (...xs) => {
22
24
  };
23
25
  export const filter = (p, f) => (x) => { if (p(x))
24
26
  f(x); };
25
- export const filterT = (p, f) => (x) => { if (p(x))
26
- f(x); };
27
27
  export const scan = (f, a) => (x) => a = f(a, x);
28
28
  export const memoize = (f, key = (...xs) => xs[0], cache = new Map()) => (...xs) => {
29
29
  const k = key(...xs);
@@ -56,3 +56,8 @@ export const toggler = (f) => {
56
56
  };
57
57
  export const voidify = (f) => (...xs) => { f(...xs); };
58
58
  export const effectual = (f, g) => disposable(d => d(f(idemp(d, g))));
59
+ export const promisify = (f) => (...xs) => Async.promisify(f(...xs));
60
+ export const then = (f, g = identity) => (...xs) => {
61
+ const r = f(...xs);
62
+ return isPromise(r) ? r.then(g) : Promise.resolve(g(r));
63
+ };
package/iterable.d.ts CHANGED
@@ -5,34 +5,22 @@ export declare const just: <T>(x: T) => IteratorObject<T>;
5
5
  export declare const enumerate: (n?: number) => <T>(x: T) => Indexed<T>;
6
6
  export declare function empty(): Generator<never, void, unknown>;
7
7
  export declare function concat<T>(...xxs: ReadonlyArray<IteratorObject<T>>): Generator<T, void, unknown>;
8
- export declare const toArray: <T>(xs: IteratorObject<T>) => T[];
9
- export declare const map: <T, U = T>(f: Fn<T, U>) => (xs: IteratorObject<T>) => IteratorObject<U, undefined, unknown>;
10
- export declare const filter: <T>(f: Pred<T>) => (xs: IteratorObject<T>) => IteratorObject<T, undefined, unknown>;
11
- export declare const drop: (n: number) => <T>(xs: IteratorObject<T>) => IteratorObject<T, undefined, unknown>;
12
- export declare const flatMap: <T, U = Iterable<T>>(f: Fn<T, Iterator<U> | Iterable<U>>) => (xs: IteratorObject<T>) => IteratorObject<U, undefined, unknown>;
13
- export declare const forEach: <T>(f?: Fn<T>) => (xs: IteratorObject<T>) => void;
14
- export declare const some: <T>(f: Pred<T>) => (xs: IteratorObject<T>) => boolean;
15
- export declare const every: <T>(f: Pred<T>) => (xs: IteratorObject<T>) => boolean;
16
- export declare const find: <T>(f: Pred<T>) => (xs: IteratorObject<T>) => T | undefined;
17
- export declare const flat: <T>(xs: IteratorObject<IteratorObject<T>>) => IteratorObject<T, undefined, unknown>;
18
8
  export declare const prepend: <A>(ys: IteratorObject<A>) => (xs: IteratorObject<A>) => Generator<A, void, unknown>;
19
9
  export declare const append: <A>(ys: IteratorObject<A>) => (xs: IteratorObject<A>) => Generator<A, void, unknown>;
20
10
  export declare const first: <T>(xs: IteratorObject<T>) => T | undefined;
21
- export declare const reduce: <T, S>(f: FnV<[S, T, number], S>, a: S) => (xs: IteratorObject<T>) => S;
22
11
  export declare const reduceRec: <T, A, R>(xs: IteratorObject<T>, f: FnV<[A, T, Fn<A>], R>, o: A, result: Fn<A, R>) => R;
23
- export declare const traverse: <T>(children: Fn<T, Iterable<T>>, f: Fn<T>) => Fn<T>;
24
- export declare const take: (n: number) => <T>(xs: IteratorObject<T>) => Generator<T>;
12
+ export declare const take: <T>(n: number, xs: IteratorObject<T>) => Generator<T, void, unknown>;
25
13
  export declare function arange(a: number, b?: number, s?: number): Generator<number, void, unknown>;
26
14
  export declare const linspace: (a: number, b: number, n: number) => Generator<number, void, unknown>;
27
15
  export declare const steps: (a: number, b: number, s?: number, o?: number, eps?: number) => Generator<number, void, unknown>;
28
- export declare const strided: (n: number, s: number) => <T>(xs: Iterable<T>) => Generator<T[], void, unknown>;
16
+ export declare const strided: <T>(n: number, s: number, xs: Iterable<T>) => Generator<T[], void, unknown>;
29
17
  export declare const stopAt: <T>(p: Pred<T>) => (xs: IteratorObject<T>) => Generator<T, void, unknown>;
30
18
  export declare const until: (p: Pred<void>) => <A>(xs: IteratorObject<A>) => Generator<A, void, unknown>;
31
19
  export type Iterators<T extends any[]> = {
32
20
  [k in keyof T]: IteratorObject<T[k]>;
33
21
  };
34
22
  export declare function zip<T extends unknown[]>(...xs: Iterators<T>): Generator<T>;
35
- export declare const iterA: <T>(xs: Promise<T>[]) => AsyncGenerator<Awaited<T>, void, unknown>;
23
+ export declare const iterA: <T>(xs: Iterable<Promise<T>>) => AsyncGenerator<Awaited<T>, void, unknown>;
36
24
  export declare const forEachA: <T>(f?: Fn<T>) => (xs: AsyncIterable<T>) => Promise<void>;
37
25
  export declare const mapA: <A, B>(f: Fn<A, B>) => Fn<AsyncIterator<A>, AsyncIterableIterator<B>>;
38
26
  export declare const flatMapA: <A, B>(f: Fn<A, Iterable<B>>) => (xs: AsyncIterator<A>) => AsyncGenerator<Awaited<B>, void, any>;
package/iterable.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { assert, isDefined } from "./checks.js";
2
- import { pipe, comp, scan, apply, noop, identity, constantly } from "./fn.js";
2
+ import { scan, apply, noop, constantly } from "./fn.js";
3
3
  import { set } from "./map.js";
4
4
  export const next = (xs) => {
5
5
  const { done, value } = xs.next();
@@ -15,20 +15,9 @@ export function* empty() { }
15
15
  export function* concat(...xxs) { for (const xs of xxs)
16
16
  yield* xs; }
17
17
  ;
18
- export const toArray = (xs) => xs.toArray();
19
- export const map = (f) => (xs) => xs.map(f);
20
- export const filter = (f) => (xs) => xs.filter(f);
21
- export const drop = (n) => (xs) => xs.drop(n);
22
- export const flatMap = (f) => (xs) => xs.flatMap(f);
23
- export const forEach = (f = noop) => (xs) => xs.forEach(f);
24
- export const some = (f) => (xs) => xs.some(f);
25
- export const every = (f) => (xs) => xs.every(f);
26
- export const find = (f) => (xs) => xs.find(f);
27
- export const flat = (xs) => xs.flatMap(identity);
28
18
  export const prepend = (ys) => (xs) => concat(ys, xs);
29
19
  export const append = (ys) => (xs) => concat(xs, ys);
30
20
  export const first = (xs) => xs.find(constantly(true));
31
- export const reduce = (f, a) => (xs) => xs.reduce(f, a);
32
21
  export const reduceRec = (xs, f, o, result) => {
33
22
  const next = (o) => {
34
23
  const { done, value } = xs.next();
@@ -39,8 +28,7 @@ export const reduceRec = (xs, f, o, result) => {
39
28
  };
40
29
  return next(o);
41
30
  };
42
- export const traverse = (children, f) => (x) => (f(x), forEach(traverse(children, f))(Iterator.from(children(x))));
43
- export const take = n => function* (xs) {
31
+ export const take = function* (n, xs) {
44
32
  for (let i = 0; i < n; i++) {
45
33
  const { done, value } = xs.next();
46
34
  if (done)
@@ -60,7 +48,7 @@ export const steps = (a, b, s = 1, o = 0, eps = 1e-8) => {
60
48
  const end = Math.floor((b - o) / s) * s + o;
61
49
  return arange(start, end + s - eps, s);
62
50
  };
63
- export const strided = (n, s) => function* (xs) {
51
+ export const strided = function* (n, s, xs) {
64
52
  const cur = [];
65
53
  for (const x of xs) {
66
54
  cur.push(x);
@@ -144,15 +132,14 @@ export const reduceA = (f, a) => async (xs) => {
144
132
  return a;
145
133
  };
146
134
  export const race = (n) => async function* (xs) {
147
- const it = pipe(xs, map(enumerate()), map(([i, x]) => [i, x.then(y => [i, y])]));
148
- const accum = reduce((set), new Map());
149
- const tasks = pipe(it, (take(n)), accum);
150
- const next = comp((take(1)), accum);
135
+ const it = xs.map((x, i) => [i, x.then(y => [i, y])]);
136
+ const acc = new Map();
137
+ const tasks = take(n, it).reduce(set, acc);
151
138
  while (tasks.size > 0) {
152
139
  const [i, x] = await Promise.race(tasks.values());
153
140
  tasks.delete(i);
154
141
  yield x;
155
- next(it);
142
+ take(1, it).reduce(set, acc);
156
143
  }
157
144
  };
158
- export const zmap = (f) => (...xs) => forEach(apply(f))(zip(...xs));
145
+ export const zmap = (f) => (...xs) => zip(...xs).forEach(apply(f));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cgtk/std",
3
- "version": "0.0.196",
3
+ "version": "0.0.198",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "exports": {
@@ -37,7 +37,7 @@
37
37
  "./npy": "./npy.js",
38
38
  "./port": "./port.js",
39
39
  "./rect": "./rect.js",
40
- "./resource": "./resource.js",
40
+ "./scope": "./scope.js",
41
41
  "./utils": "./utils.js"
42
42
  },
43
43
  "publishConfig": {
package/port.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Dispose, Fn, Fns, FnV, RecordOf, MaybePromise, Reactive } from "./types.js";
1
+ import type { Dispose, Fn, Fns, FnV, RecordOf, MaybePromise, Reactive, AsyncDispose } from "./types.js";
2
2
  export interface Message<K, V> {
3
3
  type: K;
4
4
  payload: V;
@@ -25,6 +25,6 @@ interface TransferableFnV<T extends any[], R> {
25
25
  }
26
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
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>;
28
+ export declare const startClient: (worker: Worker, f: Fn<Worker, Dispose | void>) => Promise<AsyncDispose>;
29
29
  export declare const startServer: (worker: Worker, f: Fn<Worker, MaybePromise<Dispose>>) => Promise<Dispose>;
30
30
  export {};
package/port.js CHANGED
@@ -1,7 +1,7 @@
1
- import { forEach, noop, bind } from "./fn.js";
1
+ import { noop, bind, then } from "./fn.js";
2
2
  import { isDefined } from "./checks.js";
3
3
  import { on } from "./dom.js";
4
- import { promise } from "./async.js";
4
+ import { promisify } from "./async.js";
5
5
  ;
6
6
  export const onMessages = (target, fs) => on(target, "message", ({ data: { type, payload } }) => (type in fs) && fs[type](payload));
7
7
  export const onMessage = (target, name, f) => on(target, "message", ({ data: { type, payload } }) => type == name && f(payload));
@@ -39,18 +39,18 @@ export const server = (target) => {
39
39
  onMessage(target, "rpc", async ({ id, name, args }) => {
40
40
  const f = fns.get(name);
41
41
  if (isDefined(f))
42
- rpc({ id, result: await promise(f(...args)) });
42
+ rpc({ id, result: await promisify(f(...args)) });
43
43
  });
44
44
  return new Proxy({}, {
45
45
  get: (_, k) => (f) => (fns.set(k, f), () => fns.delete(k))
46
46
  });
47
47
  };
48
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()));
49
+ const { start, stop } = client(worker);
50
+ await start();
51
+ return then(stop, f(worker) ?? noop);
52
52
  };
53
53
  export const startServer = async (worker, f) => {
54
- const ser = server(worker);
55
- return ser.start(async () => { ser.stop(await promise(f(worker))); });
54
+ const { start, stop } = server(worker);
55
+ return start(async () => { stop(await promisify(f(worker))); });
56
56
  };
package/scope.d.ts ADDED
@@ -0,0 +1,19 @@
1
+ import type { Fn, FnV, Dispose, AsyncDispose, MaybePromise, Structure } from "./types.js";
2
+ type Result = Dispose | AsyncDispose | void;
3
+ export type Scope<T> = Dispose & {
4
+ value: T;
5
+ dispose: Dispose;
6
+ map<S>(f: Fn<T, S>): Scope<S>;
7
+ use(f: Fn<T, MaybePromise<Result>>): Scope<T>;
8
+ };
9
+ export declare const scope: <T>(value: T, dispose?: Dispose) => Scope<T>;
10
+ type Unwrapped<T> = T extends Scope<infer U> ? U : {
11
+ [K in keyof T]: Unwrapped<T[K]>;
12
+ };
13
+ export declare const compose: <R extends Structure<Scope<any>>>(rs: R) => Scope<Unwrapped<R>>;
14
+ export declare const of: <T>(x: T, f: Fn<T, Dispose>) => Scope<T>;
15
+ type Use = <T>(r: Scope<T>) => T;
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
+ export declare const worker: (w: Worker) => Scope<Worker>;
19
+ export {};
package/scope.js ADDED
@@ -0,0 +1,41 @@
1
+ import * as F from "./fn.js";
2
+ import * as Async from "./async.js";
3
+ import { isPromise, isFunction } from "./checks.js";
4
+ import { add } from "./set.js";
5
+ export const scope = (value, dispose = F.noop) => {
6
+ const s = (() => dispose());
7
+ s.value = value;
8
+ s.dispose = dispose;
9
+ s.map = f => scope(f(value), dispose);
10
+ s.use = f => {
11
+ const r = f(value);
12
+ const d = isPromise(r) ?
13
+ Async.dispose(r.then(d => F.then(d ?? F.noop, dispose))) :
14
+ F.then(r ?? F.noop, dispose);
15
+ return scope(value, d);
16
+ };
17
+ return s;
18
+ };
19
+ const iLeaf = (r) => Object.hasOwn(r, "value") && Object.hasOwn(r, "dispose") && isFunction(r["dispose"]);
20
+ export const compose = (rs) => {
21
+ const disposes = [];
22
+ const rec = (rs) => {
23
+ if (iLeaf(rs)) {
24
+ disposes.push(rs.dispose);
25
+ return rs.value;
26
+ }
27
+ else if (Array.isArray(rs)) {
28
+ return rs.map(rec);
29
+ }
30
+ return Object.fromEntries(Object.entries(rs).map(([k, v]) => [k, rec(v)]));
31
+ };
32
+ const value = rec(rs);
33
+ return scope(value, F.forEach(...disposes));
34
+ };
35
+ export const of = (x, f) => scope(x, f(x));
36
+ export const gen = (f) => {
37
+ const res = new Set();
38
+ return scope(f(r => (res.add(r.dispose), r.value), F.bind(add, res)), () => res.forEach(f => f()));
39
+ };
40
+ export const consume = (f) => F.disposable(use => use(f(r => (use(r.dispose), r.value)) ?? F.noop));
41
+ export const worker = (w) => of(w, x => x.terminate.bind(x));
package/typedarray.d.ts CHANGED
@@ -24,7 +24,7 @@ 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 iter: (size: number, stride?: number) => <T extends TypedArray>(data: T) => Generator<T>;
27
+ export declare const iter: <T extends TypedArray>(data: T, size: number, stride?: number) => Generator<T>;
28
28
  export declare const tile: (n: number) => (out: TypedArray, x: TypedArray) => TypedArray;
29
29
  export declare const tileEvery: (m: number, n: number) => <T extends TypedArray>(xs: T, out?: T) => T;
30
30
  export declare const strided: <T extends TypedArray>(data: T, size: number, stride?: number, out?: T) => T;
package/typedarray.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { bind } from "./fn.js";
2
- import { zmap, map as mapI, reduce } from "./iterable.js";
2
+ import { zmap } from "./iterable.js";
3
3
  import { push } 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);
@@ -22,7 +22,7 @@ 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 iter = (size, stride = size) => function* (data) {
25
+ export const iter = function* (data, size, stride = size) {
26
26
  const C = ctor(data);
27
27
  for (let i = 0, n = data.length; i < n - size + 1; i += stride) {
28
28
  const offset = data.byteOffset + i * C.BYTES_PER_ELEMENT;
@@ -34,6 +34,6 @@ export const tile = (n) => (out, x) => {
34
34
  set(out, x, i * x.length);
35
35
  return out;
36
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);
37
+ export const tileEvery = (m, n) => (xs, out = new (ctor(xs))(xs.length * n)) => (zmap(tile(n))(iter(out, m * n), iter(xs, m)), out);
38
+ export const strided = (data, size, stride = size, out = new (ctor(data))(data.length / size * stride)) => (iter(data, size).forEach((p, i) => set(out, p, i * stride)), out);
39
+ export const toFixed = (n, sep = ',') => (xs) => Iterator.from(xs).map(x => x.toFixed(n)).reduce((push), []).join(sep);
package/types.d.ts CHANGED
@@ -14,9 +14,11 @@ export type Fns<T> = {
14
14
  };
15
15
  export type FnF = <F extends FnV>(f: F) => (...xs: Parameters<F>) => ReturnType<F>;
16
16
  export type Dispose = Fn<void>;
17
+ export type AsyncDispose = Fn<void, Promise<void>>;
17
18
  export type Reactive<T = unknown, R = any> = Fn<Fn<T, R>, Dispose>;
18
19
  export type Lazy<T> = () => T;
19
- export type MaybePromise<T = unknown> = T | PromiseLike<T>;
20
+ export type MaybePromise<T = unknown> = T | Promise<T>;
21
+ export type Promisified<T> = T extends Promise<any> ? T : Promise<T>;
20
22
  export type Last<T extends any[]> = T extends [...any, infer Rest] ? Rest : never;
21
23
  export type Tail<T extends any[]> = T extends [any, ...(infer Rest)] ? Rest : never;
22
24
  export type Push<T extends any[], V> = [...T, V];
package/resource.d.ts DELETED
@@ -1,19 +0,0 @@
1
- import type { Fn, FnV, Dispose, Structure, Reactive, RecordOf } 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
- flatMap<S>(f: Fn<T, Resource<S>>): Resource<S>;
7
- promise(f: Fn<T, Promise<Dispose | void>>): Promise<Dispose>;
8
- };
9
- export declare const resource: <T>(value: T, dispose?: Dispose) => Resource<T>;
10
- export declare const awaited: <T>({ value, dispose }: Resource<Promise<T>>) => Promise<Resource<Awaited<T>>>;
11
- type Unwrapped<T> = T extends Resource<infer U> ? U : {
12
- [K in keyof T]: Unwrapped<T[K]>;
13
- };
14
- export declare const compose: <R extends Structure<Resource<any>>>(rs: R) => Resource<Unwrapped<R>>;
15
- export declare const of: <T>(x: T, f: Fn<T, Dispose>) => Resource<T>;
16
- export declare const gen: <R>(f: FnV<[<T>(r: Resource<T>) => T, Fn<Dispose, Dispose>], R>) => Resource<R>;
17
- export declare const consume: (f: Fn<(<T>(r: Resource<T>) => T), Dispose | void>) => Dispose;
18
- export declare const swapping: <F extends RecordOf<FnV<any, Dispose | void>>>(fs: F) => Resource<{ [K in import("./types.js").Entry<keyof F, FnV<Parameters<import("./types.js").ValueOf<F>>, Dispose>> as K[0]]: K[1]; }>;
19
- export {};
package/resource.js DELETED
@@ -1,46 +0,0 @@
1
- import * as F from "./fn.js";
2
- import { isFunction } from "./checks.js";
3
- import { add } from "./set.js";
4
- import { mapValues } from "./object.js";
5
- export const resource = (value, dispose = F.noop) => {
6
- const res = ((f) => F.forEach(f(value) ?? F.noop, dispose));
7
- res.value = value;
8
- res.dispose = dispose;
9
- res.map = (f) => resource(f(value), dispose);
10
- res.flatMap = (f) => {
11
- const res = f(value);
12
- return resource(res.value, F.forEach(res.dispose, dispose));
13
- };
14
- res.promise = async (f) => F.forEach((await f(value)) ?? F.noop, dispose);
15
- return res;
16
- };
17
- export const awaited = async ({ value, dispose }) => resource(await value, dispose);
18
- const isResource = (r) => isFunction(r) &&
19
- Object.hasOwn(r, "value") &&
20
- Object.hasOwn(r, "dispose") &&
21
- isFunction(r["dispose"]);
22
- export const compose = (rs) => {
23
- const disposes = [];
24
- const rec = (rs) => {
25
- if (isResource(rs)) {
26
- disposes.push(rs.dispose);
27
- return rs.value;
28
- }
29
- else if (Array.isArray(rs)) {
30
- return rs.map(rec);
31
- }
32
- return Object.fromEntries(Object.entries(rs).map(([k, v]) => [k, rec(v)]));
33
- };
34
- const value = rec(rs);
35
- return resource(value, F.forEach(...disposes));
36
- };
37
- export const of = (x, f) => resource(x, f(x));
38
- export const gen = (f) => {
39
- const res = new Set();
40
- return resource(f((r) => (res.add(r.dispose), r.value), F.bind(add, res)), () => res.forEach((f) => f()));
41
- };
42
- export const consume = (f) => F.disposable((use) => use(f((r) => (use(r.dispose), r.value)) ?? F.noop));
43
- export const swapping = (fs) => {
44
- const swap = F.swapping();
45
- return resource(mapValues(fs, swap), swap(F.noop));
46
- };