@cgtk/std 0.0.196 → 0.0.197
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/async.d.ts +5 -6
- package/async.js +9 -24
- package/checks.d.ts +3 -0
- package/checks.js +3 -0
- package/fn.d.ts +3 -2
- package/fn.js +7 -2
- package/iterable.d.ts +1 -11
- package/iterable.js +5 -15
- package/package.json +2 -2
- package/port.d.ts +2 -2
- package/port.js +8 -8
- package/scope.d.ts +19 -0
- package/scope.js +41 -0
- package/types.d.ts +3 -1
- package/resource.d.ts +0 -19
- package/resource.js +0 -46
package/async.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
export declare const
|
|
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
|
|
6
|
-
export declare const
|
|
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 {
|
|
2
|
-
import {
|
|
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(
|
|
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
|
|
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
|
-
|
|
33
|
-
let disposed = false;
|
|
34
|
-
p.then(d =>
|
|
35
|
-
|
|
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
package/fn.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Fn, FnV, FnF, Pred,
|
|
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,23 +5,13 @@ 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
8
|
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
9
|
export declare const prepend: <A>(ys: IteratorObject<A>) => (xs: IteratorObject<A>) => Generator<A, void, unknown>;
|
|
19
10
|
export declare const append: <A>(ys: IteratorObject<A>) => (xs: IteratorObject<A>) => Generator<A, void, unknown>;
|
|
20
11
|
export declare const first: <T>(xs: IteratorObject<T>) => T | undefined;
|
|
21
12
|
export declare const reduce: <T, S>(f: FnV<[S, T, number], S>, a: S) => (xs: IteratorObject<T>) => S;
|
|
22
13
|
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
|
|
24
|
-
export declare const take: (n: number) => <T>(xs: IteratorObject<T>) => Generator<T>;
|
|
14
|
+
export declare const take: <T>(n: number, xs: IteratorObject<T>) => Generator<T, void, unknown>;
|
|
25
15
|
export declare function arange(a: number, b?: number, s?: number): Generator<number, void, unknown>;
|
|
26
16
|
export declare const linspace: (a: number, b: number, n: number) => Generator<number, void, unknown>;
|
|
27
17
|
export declare const steps: (a: number, b: number, s?: number, o?: number, eps?: number) => Generator<number, void, unknown>;
|
package/iterable.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { assert, isDefined } from "./checks.js";
|
|
2
|
-
import { pipe, comp, scan, apply, noop,
|
|
2
|
+
import { bind, pipe, comp, 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,16 +15,7 @@ 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
18
|
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
19
|
export const prepend = (ys) => (xs) => concat(ys, xs);
|
|
29
20
|
export const append = (ys) => (xs) => concat(xs, ys);
|
|
30
21
|
export const first = (xs) => xs.find(constantly(true));
|
|
@@ -39,8 +30,7 @@ export const reduceRec = (xs, f, o, result) => {
|
|
|
39
30
|
};
|
|
40
31
|
return next(o);
|
|
41
32
|
};
|
|
42
|
-
export const
|
|
43
|
-
export const take = n => function* (xs) {
|
|
33
|
+
export const take = function* (n, xs) {
|
|
44
34
|
for (let i = 0; i < n; i++) {
|
|
45
35
|
const { done, value } = xs.next();
|
|
46
36
|
if (done)
|
|
@@ -146,8 +136,8 @@ export const reduceA = (f, a) => async (xs) => {
|
|
|
146
136
|
export const race = (n) => async function* (xs) {
|
|
147
137
|
const it = pipe(xs, map(enumerate()), map(([i, x]) => [i, x.then(y => [i, y])]));
|
|
148
138
|
const accum = reduce((set), new Map());
|
|
149
|
-
const tasks = pipe(it, (take
|
|
150
|
-
const next = comp((take
|
|
139
|
+
const tasks = pipe(it, bind((take), n), accum);
|
|
140
|
+
const next = comp(bind((take), 1), accum);
|
|
151
141
|
while (tasks.size > 0) {
|
|
152
142
|
const [i, x] = await Promise.race(tasks.values());
|
|
153
143
|
tasks.delete(i);
|
|
@@ -155,4 +145,4 @@ export const race = (n) => async function* (xs) {
|
|
|
155
145
|
next(it);
|
|
156
146
|
}
|
|
157
147
|
};
|
|
158
|
-
export const zmap = (f) => (...xs) => forEach(apply(f))
|
|
148
|
+
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.
|
|
3
|
+
"version": "0.0.197",
|
|
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
|
-
"./
|
|
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<
|
|
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 {
|
|
1
|
+
import { noop, bind, then } from "./fn.js";
|
|
2
2
|
import { isDefined } from "./checks.js";
|
|
3
3
|
import { on } from "./dom.js";
|
|
4
|
-
import {
|
|
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
|
|
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
|
|
50
|
-
await
|
|
51
|
-
return
|
|
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
|
|
55
|
-
return
|
|
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/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 |
|
|
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
|
-
};
|