purity-seal 0.0.0

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 (49) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +173 -0
  3. package/dist/Build.d.ts +1 -0
  4. package/dist/Checker/Checker.pure.d.ts +59 -0
  5. package/dist/Checker/Opinion/Opinion.pure.d.ts +25 -0
  6. package/dist/Checker/Opinion/pure.d.ts +3 -0
  7. package/dist/Checker/pure.d.ts +3 -0
  8. package/dist/Checker/test.d.ts +1 -0
  9. package/dist/Classify/Classify.pure.d.ts +42 -0
  10. package/dist/Classify/Classify.test.d.ts +1 -0
  11. package/dist/Classify/File.nodejs.d.ts +3 -0
  12. package/dist/Classify/File.test.d.ts +1 -0
  13. package/dist/Classify/barrel.nodejs.d.ts +2 -0
  14. package/dist/Classify/nodejs.d.ts +3 -0
  15. package/dist/Classify/pure.d.ts +3 -0
  16. package/dist/Classify/test.d.ts +2 -0
  17. package/dist/Examples/AlternativeCheckers.test.d.ts +1 -0
  18. package/dist/Examples/IsolateRuntimes.test.d.ts +1 -0
  19. package/dist/Examples/Lua.test.d.ts +1 -0
  20. package/dist/Examples/MultipleClassifiers.test.d.ts +1 -0
  21. package/dist/Examples/OnionDiamond.test.d.ts +1 -0
  22. package/dist/Examples/StrictOrdering.test.d.ts +1 -0
  23. package/dist/Examples/test.d.ts +6 -0
  24. package/dist/Lib/Array/Array.pure.d.ts +36 -0
  25. package/dist/Lib/Array/pure.d.ts +3 -0
  26. package/dist/Lib/Function/Curry.pure.d.ts +8 -0
  27. package/dist/Lib/Function/Flow.pure.d.ts +9 -0
  28. package/dist/Lib/Function/Pipe.pure.d.ts +20 -0
  29. package/dist/Lib/Function/pure.d.ts +3 -0
  30. package/dist/Lib/Option/Option.pure.d.ts +89 -0
  31. package/dist/Lib/Option/pure.d.ts +3 -0
  32. package/dist/Lib/Reader/Reader.pure.d.ts +14 -0
  33. package/dist/Lib/Reader/pure.d.ts +3 -0
  34. package/dist/Lib/Result/Result.pure.d.ts +24 -0
  35. package/dist/Lib/Result/pure.d.ts +3 -0
  36. package/dist/Lib/Set/Set.pure.d.ts +11 -0
  37. package/dist/Lib/Set/pure.d.ts +3 -0
  38. package/dist/Lib/pure.d.ts +6 -0
  39. package/dist/Partial_Order/PartialOrder.pure.d.ts +10 -0
  40. package/dist/Partial_Order/pure.d.ts +3 -0
  41. package/dist/Partial_Order/test.d.ts +1 -0
  42. package/dist/Plugin/Lua.nodejs.d.ts +7 -0
  43. package/dist/Plugin/barrel.nodejs.d.ts +2 -0
  44. package/dist/Plugin/esbuild.nodejs.d.ts +6 -0
  45. package/dist/Plugin/nodejs.d.ts +1 -0
  46. package/dist/nodejs.d.ts +5 -0
  47. package/dist/nodejs.js +2575 -0
  48. package/dist/test.d.ts +4 -0
  49. package/package.json +32 -0
package/README.md ADDED
@@ -0,0 +1,173 @@
1
+ Purity Seal enforces dependency rules between files:
2
+
3
+ 1. Classify files `filepath -> classification`, usually by file extension. *Classifiers are composable.*
4
+ 2. Define a `partial order` that expresses dependency rules between file classifications. Partial orders may not contain cycles.
5
+ 3. Create a checker from the classifier and partial order. Checkers input a `(dependent, dependency)` string pair, and output an `opinion`. *Checkers are composable.*
6
+ 4. Run the checker against a dependency graph, typically using a build system plugin.
7
+
8
+ # Examples
9
+ - Dog food! Purity Seal [validates itself](https://github.com/muniworth/purity-seal/blob/main/Build.ts).
10
+ - [Enforce Onion Architecture](#enforce-onion-architecture)
11
+ - [Separate Business Logic from Library](#separate-business-logic-from-library)
12
+ - [Isolate Runtime Platforms](#isolate-runtime-platforms)
13
+ - [Multiple Classifiers](#multiple-classifiers)
14
+ - [Alternative Checkers](#alternative-checkers)
15
+ - [Lua](#lua)
16
+
17
+ ### Enforce Onion Architecture
18
+ ```mermaid
19
+ graph BT;
20
+ http.ts --> pure.ts
21
+ state.ts --> pure.ts
22
+ http.state.ts --> state.ts
23
+ http.state.ts --> http.ts
24
+ ```
25
+ ```ts
26
+ const classify = PS.Classify.Extensions(["pure", "state", "http"])
27
+ const po = PS.PartialOrder.Make([
28
+ [["http.state", "state.http"], ["state", "http"], "pure"],
29
+ ])
30
+ const check = PS.Pipe(
31
+ PS.Checker.Build(classify)(po),
32
+ PS.Plugin.Esbuild,
33
+ )
34
+ ```
35
+
36
+ ### Separate Business Logic from Library
37
+ ```mermaid
38
+ graph LR;
39
+ domain.ts --> pure.ts
40
+ math.ts --> domain.ts
41
+ ```
42
+ ```ts
43
+ const classify = PS.Classify.Extensions(["pure", "math", "domain"])
44
+ const po = PS.PartialOrder.Make([
45
+ ["math", "domain", "pure"],
46
+ ])
47
+ const check = PS.Pipe(
48
+ PS.Checker.Build(classify)(po),
49
+ PS.Plugin.Esbuild,
50
+ )
51
+ ```
52
+
53
+ ### Isolate Runtime Platforms
54
+ ```mermaid
55
+ graph BT;
56
+ Fetch.http.ts --> pure.ts
57
+ dom.ts --> pure.ts
58
+ worker.ts --> pure.ts
59
+ Assert.test.ts --> pure.ts
60
+
61
+ subgraph Builds
62
+ browser.ts
63
+ thread.ts
64
+ test.ts
65
+ end
66
+
67
+ browser.ts --> dom.ts
68
+ browser.ts --> Fetch.http.ts
69
+ thread.ts --> Fetch.http.ts
70
+ thread.ts --> worker.ts
71
+ test.ts --> pure.ts
72
+ test.ts --> Assert.test.ts
73
+ ```
74
+ ```ts
75
+ const classify = PS.Classify.Extensions([
76
+ "pure", "http", "dom", "worker", "test", "browser", "thread",
77
+ ])
78
+ const po = PS.PartialOrder.Make([
79
+ ["browser", ["http", "dom"], "pure"],
80
+ ["thread", ["http", "worker"], "pure"],
81
+ ["test", "pure"],
82
+ ])
83
+ const check = PS.Pipe(
84
+ PS.Checker.Build(classify)(po),
85
+ PS.Plugin.Esbuild,
86
+ )
87
+ ```
88
+
89
+ ### Multiple Classifiers
90
+ Third party code may follow different conventions.
91
+ ```mermaid
92
+ graph BT;
93
+ pure.ts --> Stats
94
+ http.ts --> pure.ts
95
+ http.ts --> HTTP
96
+ http.ts --> Framework.cache
97
+ dom.http --> http.ts
98
+ dom.http ---> Framework
99
+ ```
100
+ ```ts
101
+ const libStats = PS.Classify.SetWhen(
102
+ filepath => filepath.startsWith("node_modules/Stats"),
103
+ _filepath => "pure",
104
+ )
105
+ const libHttp = PS.Classify.SetWhen(
106
+ filepath => filepath === "node_modules/HTTP/index.ts",
107
+ _filepath => "http",
108
+ )
109
+ const libGlob = PS.Classify.SetWhen(
110
+ filepath => filepath.startsWith("node_modules/framework"),
111
+ filepath => filepath.includes("cache") ? "http" : "dom.http",
112
+ )
113
+ const classify = PS.Pipe(
114
+ PS.Classify.Extensions(["pure", "http", "dom"]),
115
+ PS.Classify.Catch(libStats),
116
+ PS.Classify.Catch(libHttp),
117
+ PS.Classify.Catch(libGlob),
118
+ )
119
+ const po = PS.PartialOrder.Make([
120
+ ["dom.http", ["dom", "http"], "pure"],
121
+ ])
122
+ const check = PS.Pipe(
123
+ PS.Checker.Build(classify)(po),
124
+ PS.Plugin.Esbuild,
125
+ )
126
+ ```
127
+
128
+ ### Alternative Checkers
129
+ A checker does not have to form an opinion for a given node in the dependency graph. Instead, you can chain multiple checkers in a pipeline, which terminates when a checker forms an opinion.
130
+ ```ts
131
+ const whitelist = new Set(["Source/Legacy/Foo.ts"])
132
+ const allowWhitelist = PS.Checker.AsksWhen(
133
+ ([x, y]) => whitelist.has(x) || whitelist.has(y),
134
+ PS.Checker.Allow(),
135
+ )
136
+ const classify = PS.Pipe(
137
+ PS.Classify.Extensions(["pure", "http"]),
138
+ )
139
+ const po = PS.PartialOrder.Make([
140
+ ["http", "pure"],
141
+ ])
142
+ const check = PS.Pipe(
143
+ PS.Checker.Build(classify)(po),
144
+ PS.Checker.Then(allowWhitelist),
145
+ PS.Plugin.Esbuild,
146
+ )
147
+ ```
148
+
149
+ ### Lua
150
+ ```mermaid
151
+ graph BT;
152
+ Player.game.lua --> pure.lua
153
+ test.lua --> pure.lua
154
+ ```
155
+ The lua tooling ecosystem is less advanced than TypeScript, so Purity Seal bundles [luaparse](https://github.com/fstirlitz/luaparse) to help extract a dependency graph.
156
+ ```ts
157
+ const classify = PS.Classify.Extensions([
158
+ "pure", "game", "test",
159
+ ])
160
+ const po = PS.PartialOrder.Make([
161
+ ["game", "pure"],// Game engine
162
+ ["test", "pure"],// CLI
163
+ ])
164
+ const check = PS.Checker.Build(classify)(po)
165
+ const deps = await PS.Plugin.Lua.BuildDeps(
166
+ // Arg 1: list of entry point modules
167
+ // resolveModule: maps modules (including entries) to raw filepath.
168
+ ["Main.game.lua", "test.lua"],
169
+ { luaVersion: "5.1", resolveModule: x => "source/" + x },
170
+ )
171
+ // { deny: Deps[], warn: string[] }
172
+ const out = PS.Checker.Validate(check, deps)
173
+ ```
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,59 @@
1
+ import { Classify } from "../Classify/pure.ts";
2
+ import { Reader, Result } from "../Lib/pure.ts";
3
+ import { Opinion } from "./Opinion/pure.ts";
4
+ import { PartialOrder } from "../Partial_Order/pure.ts";
5
+ export * from "./Opinion/pure.ts";
6
+ /** Reader environment: Dependent, Dependency */
7
+ export type Deps = readonly [string, string];
8
+ export type Checker<A> = Reader<Deps, Opinion<A>>;
9
+ export declare const Pure: <A>(val: A) => Checker<A>;
10
+ export declare const Allow: <A = never>() => Checker<A>;
11
+ export declare const Deny: <A = never>() => Checker<A>;
12
+ export declare const Warn: <A = never>(x: string) => Checker<A>;
13
+ export declare const Bind_: <A, B>(m: Checker<A>, f: (t: A) => Checker<B>) => (d: Deps) => import("./Opinion/Opinion.pure.ts").Opinion<B>;
14
+ export declare const Bind: {
15
+ <A, B>(m: Checker<A>, f: (t: A) => Checker<B>): Checker<B>;
16
+ <A, B>(f: (t: A) => Checker<B>): (m: Checker<A>) => Checker<B>;
17
+ };
18
+ export declare const Map_: <A, B>(m: Checker<A>, f: (t: A) => B) => (d: Deps) => import("./Opinion/Opinion.pure.ts").Opinion<B>;
19
+ export declare const Map: {
20
+ <A, B>(m: Checker<A>, f: (t: A) => B): Checker<B>;
21
+ <A, B>(f: (t: A) => B): (m: Checker<A>) => Checker<B>;
22
+ };
23
+ export declare const Asks: <A>(f: (d: Deps) => A) => Checker<A>;
24
+ export declare const Ask: Checker<Deps>;
25
+ export declare const Then_: <A, B>(m1: Checker<A>, m2: Checker<B>) => Checker<B>;
26
+ export declare const Then: {
27
+ <A, B>(m1: Checker<A>, m2: Checker<B>): Checker<B>;
28
+ <A, B>(m2: Checker<B>): (m1: Checker<A>) => Checker<B>;
29
+ };
30
+ export declare const When_: (b: boolean, m: Checker<void>) => Checker<void>;
31
+ export declare const When: {
32
+ (b: boolean, m: Checker<void>): Checker<void>;
33
+ (m: Checker<void>): (b: boolean) => Checker<void>;
34
+ };
35
+ export declare const AsksWhen_: (p: (d: Deps) => boolean, m: Checker<void>) => Checker<void>;
36
+ export declare const AsksWhen: {
37
+ (p: (d: Deps) => boolean, m: Checker<void>): Checker<void>;
38
+ (m: Checker<void>): (p: (d: Deps) => boolean) => Checker<void>;
39
+ };
40
+ export declare const IfM_: <A>(mp: Checker<boolean>, m1: Checker<A>, m2: Checker<A>) => Checker<A>;
41
+ export declare const IfM: {
42
+ <A>(mp: Checker<boolean>, m1: Checker<A>, m2: Checker<A>): Checker<A>;
43
+ <A>(m1: Checker<A>, m2: Checker<A>): (mp: Checker<boolean>) => Checker<A>;
44
+ };
45
+ /** Create a Checker that first classifies paths to file extensions,
46
+ * then compares the resulting classes in the partial order generated by
47
+ * relations `orderRules`. More specifically, for each file with class `X`
48
+ * importing a file of class `Y`, we must have `X < Y` in the partial order.
49
+ *
50
+ * If either the dependent or dependency file don't match any rule in
51
+ * `classRules`, then the returned checker behaves as `Pure(undefined)` (i.e.,
52
+ * it has "no opinion" on whether the file should be allowed or rejected).
53
+ */
54
+ export declare const Build: <T extends string>(classify: Classify<Classify.GlobExtension<T>>) => (partialOrder: Result<PartialOrder<Classify.GlobExtension<T>>, string>) => Checker<void>;
55
+ type CheckerResult = {
56
+ deny: Deps[];
57
+ warn: string[];
58
+ };
59
+ export declare const Validate: (check: Checker<void>, deps: Deps[]) => CheckerResult;
@@ -0,0 +1,25 @@
1
+ import type { Deps } from "../Checker.pure.ts";
2
+ /** Pure is the monad success case for checker pipelines
3
+ * to continue running, i.e. Pure = Undecided.
4
+ *
5
+ * All other states are failure cases,
6
+ * i.e. they terminate checking with a decision.
7
+ */
8
+ export type Opinion<A> = {
9
+ _tag: "Pure";
10
+ Value: A;
11
+ } | {
12
+ _tag: "Allow";
13
+ } | {
14
+ _tag: "Deny";
15
+ Deps: Deps;
16
+ } | {
17
+ _tag: "Warn";
18
+ Message: string;
19
+ };
20
+ export declare const Pure: <A>(a: A) => Opinion<A>;
21
+ export declare const Allow: () => Opinion<never>;
22
+ export declare const Deny: (d: Deps) => Opinion<never>;
23
+ export declare const Warn: (x: string) => Opinion<never>;
24
+ export declare const Map: <A, B>(m: Opinion<A>, f: (a: A) => B) => Opinion<B>;
25
+ export declare const Bind: <A, B>(m: Opinion<A>, f: (t: A) => Opinion<B>) => Opinion<B>;
@@ -0,0 +1,3 @@
1
+ import type { Opinion as m } from "./Opinion.pure.ts";
2
+ export * as Opinion from "./Opinion.pure.ts";
3
+ export type Opinion<A> = m<A>;
@@ -0,0 +1,3 @@
1
+ import type { Checker as checker } from "./Checker.pure.ts";
2
+ export * as Checker from "./Checker.pure.ts";
3
+ export type Checker<A> = checker<A>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { Option, Reader } from "../Lib/pure.ts";
2
+ type ext = string;
3
+ export type GlobExtension<T extends string> = T | `${T}.${T}`;
4
+ export type Classify<A> = Reader<ext, Option<A>>;
5
+ export declare const Pure: <A>(a: A) => Classify<A>;
6
+ export declare const None: <A = never>() => Classify<A>;
7
+ export declare const Map_: <A, B>(m: Classify<A>, f: (a: A) => B) => import("../Lib/Reader/Reader.pure.ts").Reader<string, import("../Lib/Option/Option.pure.ts").Option<B>>;
8
+ export declare const Map: {
9
+ <A, B>(m: Classify<A>, f: (a: A) => B): Classify<B>;
10
+ <A, B>(f: (a: A) => B): ((m: Classify<A>) => Classify<B>);
11
+ };
12
+ export declare const Bind_: <A, B>(m: Classify<A>, f: (t: A) => Classify<B>) => (ext: ext) => import("../Lib/Option/Option.pure.ts").Option<B>;
13
+ export declare const Bind: {
14
+ <A, B>(m: Classify<A>, f: (t: A) => Classify<B>): Classify<B>;
15
+ <A, B>(f: (t: A) => Classify<B>): (m: Classify<A>) => Classify<B>;
16
+ };
17
+ export declare const BindOption_: <A, B>(m: Classify<A>, f: (a: A) => Option<B>) => Classify<B>;
18
+ export declare const BindOption: {
19
+ <A, B>(m: Classify<A>, f: (a: A) => Option<B>): Classify<B>;
20
+ <A, B>(f: (a: A) => Option<B>): ((m: Classify<A>) => Classify<B>);
21
+ };
22
+ /** Fusion of Ask (Id) and Map. */
23
+ export declare const Asks: <A>(f: (ext: ext) => A) => (ext: ext) => import("../Lib/Option/Option.pure.ts").Option<A>;
24
+ export declare const Catch_: <A, B>(m1: Classify<A>, m2: Classify<B>) => Classify<A | B>;
25
+ /** Recover if a classifier fails to match an extension. */
26
+ export declare const Catch: {
27
+ <A, B>(m1: Classify<A>, m2: Classify<B>): Classify<A | B>;
28
+ <A, B>(m2: Classify<B>): (m1: Classify<A>) => Classify<A | B>;
29
+ };
30
+ export declare const AsksWhen_: <A extends string>(p: (ext: ext) => boolean, m: Classify<A>) => Classify<A>;
31
+ /** Use a classifier if the filepath satisfies a predicate. */
32
+ export declare const AsksWhen: {
33
+ <A extends string>(p: (ext: ext) => boolean, m: Classify<A>): Classify<A>;
34
+ <A extends string>(m: Classify<A>): (p: (ext: ext) => boolean) => Classify<A>;
35
+ };
36
+ export declare const SetWhen_: <A extends string>(p: (ext: ext) => boolean, f: (ext: ext) => A) => Classify<A>;
37
+ /** Set the file classification if the filepath satisfies a predicate. */
38
+ export declare const SetWhen: {
39
+ <A extends string>(p: (ext: ext) => boolean, f: (ext: ext) => A): Classify<A>;
40
+ <A extends string>(f: (ext: ext) => A): (p: (ext: ext) => boolean) => Classify<A>;
41
+ };
42
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { Classify } from "./pure.ts";
2
+ /** Create list of filename -> extension matchers. Order does not matter. */
3
+ export declare const Extensions: <A extends string>(extIter: Iterable<A>) => Classify<Classify.GlobExtension<A>>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export * from "./Classify.pure.ts";
2
+ export * from "./File.nodejs.ts";
@@ -0,0 +1,3 @@
1
+ import type { Classify as m } from "./Classify.pure.ts";
2
+ export * as Classify from "./barrel.nodejs.ts";
3
+ export type Classify<A> = m<A>;
@@ -0,0 +1,3 @@
1
+ import type { Classify as m } from "./Classify.pure.ts";
2
+ export * as Classify from "./Classify.pure.ts";
3
+ export type Classify<A> = m<A>;
@@ -0,0 +1,2 @@
1
+ import "./Classify.test.ts";
2
+ import "./File.test.ts";
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,6 @@
1
+ import "./AlternativeCheckers.test.ts";
2
+ import "./IsolateRuntimes.test.ts";
3
+ import "./Lua.test.ts";
4
+ import "./MultipleClassifiers.test.ts";
5
+ import "./OnionDiamond.test.ts";
6
+ import "./StrictOrdering.test.ts";
@@ -0,0 +1,36 @@
1
+ import { Option } from "../Option/pure.ts";
2
+ export type Array<A> = globalThis.ReadonlyArray<A>;
3
+ export type ArrayMut<A> = globalThis.Array<A>;
4
+ export type NonEmpty<A> = readonly [A, ...A[]];
5
+ export type NonEmptyMut<A> = [A, ...A[]];
6
+ export type Infer<S extends Array<any>> = S extends Array<infer A> ? A : never;
7
+ export type AndEmpty1<Zs extends Array<unknown>, R> = Zs extends NonEmpty<unknown> ? NonEmptyMut<R> : R[];
8
+ export type AndEmpty2<Ys extends Array<unknown>, Zs extends Array<unknown>, R> = Zs extends NonEmptyMut<unknown> ? (Ys extends NonEmptyMut<unknown> ? NonEmptyMut<R> : R[]) : R[];
9
+ export declare const IsNonEmpty: {
10
+ <A>(xs: Array<A>): xs is NonEmpty<A>;
11
+ <A>(xs: A[]): xs is NonEmptyMut<A>;
12
+ };
13
+ export declare const Bind_: <A extends Array<any>, B>(f: (a: Infer<A>, i: number) => B[]) => (xs: A) => B[];
14
+ export declare const Bind: {
15
+ <A extends Array<any>, B>(xs: A, f: (a: Infer<A>, i: number) => NonEmptyMut<B>): AndEmpty1<A, B>;
16
+ <A extends Array<any>, B>(xs: A, f: (a: Infer<A>, i: number) => B[]): B[];
17
+ <A extends Array<any>, B>(f: (a: Infer<A>, i: number) => NonEmptyMut<B>): (xs: A) => AndEmpty1<A, B>;
18
+ <A extends Array<any>, B>(f: (a: Infer<A>, i: number) => B[]): (xs: A) => B[];
19
+ };
20
+ export declare const Choose_: <A, B>(xs: Array<A>, chooser: (x: A, i: number) => Option<B>) => B[];
21
+ export declare const Choose: {
22
+ <A, B>(xs: Array<A>, chooser: (x: A, i: number) => Option<B>): B[];
23
+ <A, B>(chooser: (x: A, i: number) => Option<B>): (xs: Array<A>) => B[];
24
+ };
25
+ export declare const Filter_: <A>(xs: Array<A>, pred: (a: A, i: number) => boolean) => A[];
26
+ export declare const Filter: {
27
+ <A, B extends A>(xs: Array<A>, refine: (a: A, i: number) => a is B): B[];
28
+ <A, B extends A>(refine: (a: A, i: number) => a is B): (xs: Array<A>) => B[];
29
+ <A>(xs: Array<A>, pred: (a: A, i: number) => boolean): A[];
30
+ <A>(pred: (a: NoInfer<A>, i: number) => boolean): (xs: Array<A>) => A[];
31
+ };
32
+ export declare const Map_: <A extends Array<any>, B>(xs: A, f: (a: Infer<A>, i: number) => B) => AndEmpty1<A, B>;
33
+ export declare const Map: {
34
+ <A extends Array<any>, B>(f: (a: Infer<A>, i: number) => B): (xs: A) => AndEmpty1<A, B>;
35
+ <A extends Array<any>, B>(xs: A, f: (a: Infer<A>, i: number) => B): AndEmpty1<A, B>;
36
+ };
@@ -0,0 +1,3 @@
1
+ import type { Array as m } from "./Array.pure.ts";
2
+ export * as Array from "./Array.pure.ts";
3
+ export type Array<A> = m<A>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Transforms a function parameterization into two call modes:
3
+ * 1. Unchanged.
4
+ * 2. Partial application, with parameters rotated at the pivot point.
5
+ *
6
+ * Requires explicit type overloads to reflect runtime behavior. Inspired by 'dual' in Effect-TS.
7
+ */
8
+ export declare const CurryRev: <Original extends (...args: Array<any>) => any, Curried extends (...args: Array<any>) => any>(body: Original) => Curried;
@@ -0,0 +1,9 @@
1
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never>(ab: (...a: A) => B): (...a: A) => B;
2
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never>(ab: (...a: A) => B, bc: (b: B) => C): (...a: A) => C;
3
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...a: A) => D;
4
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): (...a: A) => E;
5
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F): (...a: A) => F;
6
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): (...a: A) => G;
7
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never, H = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): (...a: A) => H;
8
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): (...a: A) => I;
9
+ export declare function Flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J): (...a: A) => J;
@@ -0,0 +1,20 @@
1
+ export declare function Pipe<A>(a: A): A;
2
+ export declare function Pipe<A, B = never>(a: A, ab: (a: A) => B): B;
3
+ export declare function Pipe<A, B = never, C = never>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
4
+ export declare function Pipe<A, B = never, C = never, D = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;
5
+ export declare function Pipe<A, B = never, C = never, D = never, E = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E;
6
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F): F;
7
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): G;
8
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): H;
9
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): I;
10
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J): J;
11
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K): K;
12
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L): L;
13
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M): M;
14
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N): N;
15
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O): O;
16
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P): P;
17
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q): Q;
18
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R): R;
19
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S): S;
20
+ export declare function Pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T): T;
@@ -0,0 +1,3 @@
1
+ export { CurryRev } from "./Curry.pure.ts";
2
+ export { Flow } from "./Flow.pure.ts";
3
+ export { Pipe } from "./Pipe.pure.ts";
@@ -0,0 +1,89 @@
1
+ export type Some<A> = {
2
+ readonly _tag: "Some";
3
+ readonly value: A;
4
+ };
5
+ export type None<A = never> = {
6
+ readonly _tag: "None";
7
+ };
8
+ export type Option<A> = Some<A> | None<A>;
9
+ /** Lifts a value to an Option. */
10
+ export declare const Some: <A>(value: A) => Option<A>;
11
+ /** Returns 'None' for a given type. */
12
+ export declare const None: <A = never>() => Option<A>;
13
+ /** Converts a nullable value into an Option */
14
+ export declare const OfNullable: <A>(value: A | null | undefined) => Option<NonNullable<A>>;
15
+ export declare const Some_Filter_: <A>(a: A, pred: (a: A) => boolean) => Option<A>;
16
+ export declare const Some_Filter: {
17
+ <A>(a: A, pred: (a: A) => boolean): Option<A>;
18
+ <A>(pred: (a: A) => boolean): (a: A) => Option<A>;
19
+ };
20
+ /** Returns `true` if it is a `Some` */
21
+ export declare const IsSome: <A>(opt: Option<A>) => opt is Some<A>;
22
+ /** Returns `true` if it is a `None` */
23
+ export declare const IsNone: <A>(opt: Option<A>) => opt is None<A>;
24
+ /** Combines all Options in a tuple if they are `Some`
25
+ *
26
+ * @example All([Some(1), Some("a")]) = Some([1, "a"])
27
+ *
28
+ * @example All([Some(1), None(), None()]) = None() */
29
+ export declare const All: <const Os extends readonly Option<unknown>[]>(os: readonly Option<unknown>[] & Os) => Option<{ [K in keyof Os]: Os[K] extends Option<infer A> ? A : never; }>;
30
+ export declare const Bind_: <A, B>(opt: Option<A>, f: (a: A) => Option<B>) => Option<B>;
31
+ export declare const Bind: {
32
+ <A, B>(opt: Option<A>, f: (a: A) => Option<B>): Option<B>;
33
+ <A, B>(f: (a: A) => Option<B>): (opt: Option<A>) => Option<B>;
34
+ };
35
+ export declare const Map_: <A, B>(opt: Option<A>, f: (a: A) => B) => Option<B>;
36
+ export declare const Map: {
37
+ <A, B>(opt: Option<A>, f: (a: A) => B): Option<B>;
38
+ <A, B>(f: (a: A) => B): (opt: Option<A>) => Option<B>;
39
+ };
40
+ export declare const Catch_: <A, B>(opt: Option<A>, f: () => Option<B>) => Option<A | B>;
41
+ export declare const Catch: {
42
+ <A, B>(opt: Option<A>, f: () => Option<B>): Option<A | B>;
43
+ <A, B>(f: () => Option<B>): (opt: Option<A>) => Option<A | B>;
44
+ };
45
+ /** Gets the value of a `Some`, or returns some fallback value */
46
+ export declare const Default_: <A, B = A>(opt: Option<A>, fallback: B) => A | B;
47
+ /** Gets the value of a `Some`, or returns some fallback value */
48
+ export declare const Default: {
49
+ <A, B = A>(opt: Option<A>, fallback: B): A | B;
50
+ <B>(fallback: B): <A = B>(opt: Option<A>) => A | B;
51
+ };
52
+ /** Gets the value of a `Some`, or returns some fallback function */
53
+ export declare const DefaultLazy_: <A, B = A>(opt: Option<A>, fallback: () => B) => A | B;
54
+ /** Gets the value of a `Some`, or returns some fallback function */
55
+ export declare const DefaultLazy: {
56
+ <A, B = A>(opt: Option<A>, fallback: () => B): A | B;
57
+ <B>(fallback: () => B): <A = B>(opt: Option<A>) => A | B;
58
+ };
59
+ export declare const Elim_: <A, B, C>(opt: Option<A>, fallback: B, f: (x: A) => C) => B | C;
60
+ /** Applies a function to an option and then returns either the value or a fallback */
61
+ export declare const Elim: {
62
+ <A, B, C>(opt: Option<A>, fallback: B, f: (x: A) => C): B | C;
63
+ <A, B, C>(fallback: B, f: (x: A) => C): (opt: Option<A>) => B | C;
64
+ };
65
+ export declare const ElimLazy_: <A, B, C>(opt: Option<A>, fallback: () => B, f: (x: A) => C) => B | C;
66
+ /** Applies a function to an option and then returns either the value or a lazy fallback */
67
+ export declare const ElimLazy: {
68
+ <A, B, C>(opt: Option<A>, fallback: () => B, f: (x: A) => C): B | C;
69
+ <A, B, C>(fallback: () => B, f: (x: A) => C): (opt: Option<A>) => B | C;
70
+ };
71
+ export declare const Match_: <A, M1, M2>(opt: Option<A>, handlers: {
72
+ onSome: (value: A) => M1;
73
+ onNone: () => M2;
74
+ }) => M1 | M2;
75
+ /** Performs different actions dependant on the Option being `Some` or `None` */
76
+ export declare const Match: {
77
+ <A, M>(opt: Option<A>, handlers: {
78
+ onSome: (value: A) => M;
79
+ onNone: () => M;
80
+ }): M;
81
+ <A, M1, M2>(opt: Option<A>, handlers: {
82
+ onSome: (value: A) => M1;
83
+ onNone: () => M2;
84
+ }): M1 | M2;
85
+ <A, M1, M2>(handlers: {
86
+ onSome: (value: A) => M1;
87
+ onNone: () => M2;
88
+ }): (opt: Option<A>) => M1 | M2;
89
+ };
@@ -0,0 +1,3 @@
1
+ import type { Option as m } from "./Option.pure.ts";
2
+ export * as Option from "./Option.pure.ts";
3
+ export type Option<A> = m<A>;
@@ -0,0 +1,14 @@
1
+ export type Reader<Env, A> = (env: Env) => A;
2
+ export declare const Pure: <Env = void, A = unknown>(a: A) => Reader<Env, A>;
3
+ export declare const Map_: <Env, A, B>(m: Reader<Env, A>, f: (a: A) => B) => Reader<Env, B>;
4
+ export declare const Map: {
5
+ <Env, A, B>(m: Reader<Env, A>, f: (a: A) => B): Reader<Env, B>;
6
+ <Env, A, B>(f: (a: A) => B): ((m: Reader<Env, A>) => Reader<Env, B>);
7
+ };
8
+ export declare const Bind_: <Env, A, B>(m: Reader<Env, A>, f: (a: A) => Reader<Env, B>) => Reader<Env, B>;
9
+ export declare const Bind: {
10
+ <Env, A, B>(m: Reader<Env, A>, f: (a: A) => Reader<Env, B>): Reader<Env, B>;
11
+ <Env, A, B>(f: (a: A) => Reader<Env, B>): ((m: Reader<Env, A>) => Reader<Env, B>);
12
+ };
13
+ /** Fusion of Ask (Id) and Map. */
14
+ export declare const Asks: <Env, A>(f: (env: Env) => A) => Reader<Env, A>;
@@ -0,0 +1,3 @@
1
+ import type { Reader as reader } from "./Reader.pure.ts";
2
+ export * as Reader from "./Reader.pure.ts";
3
+ export type Reader<Env, A> = reader<Env, A>;
@@ -0,0 +1,24 @@
1
+ export type Ok<A, E = never> = {
2
+ readonly _tag: "Ok";
3
+ readonly value: A;
4
+ };
5
+ export type Error<A = never, E = unknown> = {
6
+ readonly _tag: "Error";
7
+ readonly error: E;
8
+ };
9
+ export type Result<A, E> = Ok<A, E> | Error<A, E>;
10
+ /** Lifts a value to a Result of type `Ok` */
11
+ export declare const Ok: <A, E = never>(value: A) => Result<A, E>;
12
+ /** Lifts a value to a Result of type `Error` */
13
+ export declare const Error: <E, A = never>(reason: E) => Result<A, E>;
14
+ /** Returns `true` if it is an `Ok` */
15
+ export declare const IsOk: <A, E>(res: Result<A, E>) => res is Ok<A, E>;
16
+ /** Returns `true` if it is an `Error` */
17
+ export declare const IsError: <A, E>(res: Result<A, E>) => res is Error<A, E>;
18
+ export declare const Map_: <A, E, B>(res: Result<A, E>, f: (a: A) => B) => Result<B, E>;
19
+ /** Applies some function to modify the `Ok` case */
20
+ export declare const Map: {
21
+ <A, E, B>(res: Result<A, E>, f: (a: A) => B): Result<B, E>;
22
+ <A, B>(f: (a: A) => B): <E>(res: Result<A, E>) => Result<B, E>;
23
+ };
24
+ export declare const GetOrThrow: <A, E>(res: Result<A, E>) => A;
@@ -0,0 +1,3 @@
1
+ import type { Result as m } from "./Result.pure.ts";
2
+ export * as Result from "./Result.pure.ts";
3
+ export type Result<A, E> = m<A, E>;
@@ -0,0 +1,11 @@
1
+ import type { Comparable, WidenComparable } from "../Util.pure.d.ts";
2
+ export type Set<A> = globalThis.ReadonlySet<A>;
3
+ export type SetMut<A> = globalThis.Set<A>;
4
+ export declare const Empty: <T>() => ReadonlySet<T>;
5
+ export declare const Empty_Mut: <T>() => SetMut<T>;
6
+ export declare const Singleton: <T>(x: T) => SetMut<T>;
7
+ export declare const FromIterable: <T>(xs: Iterable<T>) => SetMut<T>;
8
+ export declare const ToArray: <T>(set: ReadonlySet<T>) => T[];
9
+ export declare const ToMutable: <T>(set: ReadonlySet<T>) => SetMut<T>;
10
+ /** @alias Contains, Includes, Member */
11
+ export declare const Has: <A extends Comparable>(xs: Set<A>, y: A | WidenComparable<A>) => y is A;
@@ -0,0 +1,3 @@
1
+ import type { Set as m } from "./Set.pure.ts";
2
+ export * as Set from "./Set.pure.ts";
3
+ export type Set<A> = m<A>;