functionalscript 0.0.153 → 0.0.157
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/{lib/tree/array.js → array/index.js} +0 -0
- package/async/index.js +101 -0
- package/async/test.js +24 -0
- package/{lib/tree → btree}/README.md +0 -0
- package/{lib/tree → btree}/index.js +9 -9
- package/{lib/tree/cmp.js → cmp/index.js} +3 -3
- package/index.js +0 -4
- package/{lib/iterable → iterable}/index.js +13 -17
- package/iterable/test.js +41 -0
- package/lib/index.js +1 -61
- package/lib/test.js +2 -2
- package/{lib/map → map}/index.js +8 -8
- package/{lib/map → map}/test.js +10 -11
- package/map-reduce/index.js +42 -0
- package/module-manager/index.js +11 -5
- package/module-manager/test.js +22 -23
- package/package.json +1 -1
- package/test.js +3 -2
- package/lib/iterable/test.js +0 -41
- package/lib/tree/lazy.js +0 -6
- package/module-manager/test0.js +0 -1
- package/module-manager/test0.js.js +0 -1
|
File without changes
|
package/async/index.js
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
const { pipe } = require('../lib')
|
|
2
|
+
|
|
3
|
+
/** @type {<T, R>(f: (value: T) => Promise<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
|
|
4
|
+
const map = f => c => ({
|
|
5
|
+
async *[Symbol.asyncIterator]() {
|
|
6
|
+
for await (const i of c) {
|
|
7
|
+
yield f(i)
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
/** @type {<T>(c: AsyncIterable<AsyncIterable<T>>) => AsyncIterable<T>} */
|
|
13
|
+
const flatten = c => ({
|
|
14
|
+
async *[Symbol.asyncIterator]() {
|
|
15
|
+
for await (const i of c) {
|
|
16
|
+
yield *i
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
/** @type {<T>(f: (value: T) => Promise<boolean>) => (c: AsyncIterable<T>) => AsyncIterable<T>} */
|
|
22
|
+
const filter = f => c => ({
|
|
23
|
+
async *[Symbol.asyncIterator]() {
|
|
24
|
+
for await (const i of c) {
|
|
25
|
+
if (await f(i)) {
|
|
26
|
+
yield i
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
/** @type {<T, R>(f: (value: T) => AsyncIterable<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>} */
|
|
33
|
+
const flatMap = f => pipe(map(async x => f(x)))(flatten)
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @template A
|
|
37
|
+
* @template T
|
|
38
|
+
* @typedef {(accumulator: A) => (value: T) => Promise<A>} ReduceFn
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/** @type {<A, T>(f: ReduceFn<A, T>) => (init: A) => (c: AsyncIterable<T>) => Promise<A>} */
|
|
42
|
+
const reduce = reduceFn => init => async c => {
|
|
43
|
+
let result = init
|
|
44
|
+
for await (const i of c) {
|
|
45
|
+
result = await reduceFn(result)(i)
|
|
46
|
+
}
|
|
47
|
+
return result
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @type {<A, T>(f: ReduceFn<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
|
|
51
|
+
const exclusiveScan = reduceFn => init => c => ({
|
|
52
|
+
async *[Symbol.asyncIterator]() {
|
|
53
|
+
let result = init
|
|
54
|
+
for await (const i of c) {
|
|
55
|
+
result = await reduceFn(result)(i)
|
|
56
|
+
yield result
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
/** @type {<A, T>(f: ReduceFn<A, T>) => (init: A) => (c: AsyncIterable<T>) => AsyncIterable<A>} */
|
|
62
|
+
const inclusiveScan = reduceFn => init => {
|
|
63
|
+
const e = exclusiveScan(reduceFn)(init)
|
|
64
|
+
return c => ({
|
|
65
|
+
async *[Symbol.asyncIterator]() {
|
|
66
|
+
yield init
|
|
67
|
+
yield *e(c)
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @type {<T>(iterable: Iterable<T>) => AsyncIterable<T>} */
|
|
73
|
+
const cast = iterable => ({
|
|
74
|
+
async *[Symbol.asyncIterator]() {
|
|
75
|
+
for (const i of iterable) {
|
|
76
|
+
yield i
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
/** @type {(c: AsyncIterable<number>) => Promise<number>} */
|
|
82
|
+
const sum = reduce(a => async v => a + v)(0)
|
|
83
|
+
|
|
84
|
+
module.exports = {
|
|
85
|
+
/** @readonly */
|
|
86
|
+
cast,
|
|
87
|
+
/** @readonly */
|
|
88
|
+
map,
|
|
89
|
+
/** @readonly */
|
|
90
|
+
filter,
|
|
91
|
+
/** @readonly */
|
|
92
|
+
flatMap,
|
|
93
|
+
/** @readonly */
|
|
94
|
+
reduce,
|
|
95
|
+
/** @readonly */
|
|
96
|
+
sum,
|
|
97
|
+
/** @readonly */
|
|
98
|
+
exclusiveScan,
|
|
99
|
+
/** @readonly */
|
|
100
|
+
inclusiveScan,
|
|
101
|
+
}
|
package/async/test.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const { cast, map, filter, flatMap, sum } = require('.')
|
|
2
|
+
|
|
3
|
+
const test = async () => {
|
|
4
|
+
{
|
|
5
|
+
const a = cast([1, 2, 3])
|
|
6
|
+
const m = map(async x => x * x)(a)
|
|
7
|
+
const result = await sum(m)
|
|
8
|
+
if (result !== 14) { throw 'filter' }
|
|
9
|
+
}
|
|
10
|
+
{
|
|
11
|
+
const a = cast([1, 2, 3, 4])
|
|
12
|
+
const f = filter(async x => x !== 2)(a)
|
|
13
|
+
const result = await sum(f)
|
|
14
|
+
if (result !== 8) { throw 'filter' }
|
|
15
|
+
}
|
|
16
|
+
{
|
|
17
|
+
const a = cast([1, 2])
|
|
18
|
+
const f = flatMap(x => cast([x, x * x]))(a)
|
|
19
|
+
const result = await sum(f)
|
|
20
|
+
if (result !== 8) { throw 'filter' }
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
test()
|
|
File without changes
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
const { index3, index5 } = require('
|
|
1
|
+
const { index3, index5 } = require('../cmp')
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @template T
|
|
5
|
-
* @typedef {
|
|
5
|
+
* @typedef {() => T} Lazy
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* @template T
|
|
10
|
-
* @typedef {import('
|
|
10
|
+
* @typedef {import('../cmp').Cmp<T>} Cmp
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @template T
|
|
15
|
-
* @typedef {import('
|
|
15
|
+
* @typedef {import('../array').Array1<T>} Array1
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* @template T
|
|
20
|
-
* @typedef {import('
|
|
20
|
+
* @typedef {import('../array').Array2<T>} Array2
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* @template T
|
|
25
|
-
* @typedef {import('
|
|
25
|
+
* @typedef {import('../array').Array3<T>} Array3
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
/** @typedef {import('
|
|
28
|
+
/** @typedef {import('../array').Index2} Index2 */
|
|
29
29
|
|
|
30
|
-
/** @typedef {import('
|
|
30
|
+
/** @typedef {import('../array').Index3} Index3 */
|
|
31
31
|
|
|
32
|
-
/** @typedef {import('
|
|
32
|
+
/** @typedef {import('../array').Index5} Index5 */
|
|
33
33
|
|
|
34
34
|
//
|
|
35
35
|
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/** @typedef {import('
|
|
2
|
-
/** @typedef {import('
|
|
1
|
+
/** @typedef {import('../array').Index3} Index3 */
|
|
2
|
+
/** @typedef {import('../array').Index5} Index5 */
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* @template T
|
|
6
|
-
* @typedef {import('
|
|
6
|
+
* @typedef {import('../array').Array2<T>} Array2
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
/** @typedef {-1|0|1} Sign */
|
package/index.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
1
|
const lib = require('./lib')
|
|
4
2
|
|
|
5
|
-
const todo = () => lib.panic('not implemented')
|
|
6
|
-
|
|
7
3
|
/** @type {<F>(c: string, found: (before: string, after: string) => F, notFound: (c: string, source: string) => F) => (source: string) => F} */
|
|
8
4
|
const splitOne = (c, found, notFound) => source => {
|
|
9
5
|
const i = source.indexOf(c)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
const
|
|
1
|
+
const { pipe } = require('../lib')
|
|
2
|
+
const lib = require('../lib')
|
|
3
|
+
const mr = require('../map-reduce')
|
|
2
4
|
|
|
3
|
-
/** @type {<T, R>(_:
|
|
4
|
-
const reduce =
|
|
5
|
+
/** @type {<T, R>(merge: (_: R) => (_: T) => R) => (init: R) => (_: Iterable<T>) => R} */
|
|
6
|
+
const reduce = merge => init => c => {
|
|
5
7
|
let result = init
|
|
6
8
|
for (const i of c) {
|
|
7
9
|
result = merge(result)(i)
|
|
@@ -9,15 +11,21 @@ const reduce = ({ merge, init }) => c => {
|
|
|
9
11
|
return result
|
|
10
12
|
}
|
|
11
13
|
|
|
14
|
+
/** @type {<I, S, R>(op: mr.Operation<I, S, R>) => (_: Iterable<I>) => R} */
|
|
15
|
+
const apply = op => pipe(reduce(op.reduce)(op.init))(op.result)
|
|
16
|
+
|
|
12
17
|
module.exports = {
|
|
18
|
+
/** @readonly */
|
|
19
|
+
apply,
|
|
20
|
+
|
|
13
21
|
/** @readonly */
|
|
14
22
|
reduce,
|
|
15
23
|
|
|
16
24
|
/** @readonly */
|
|
17
|
-
join:
|
|
25
|
+
join: pipe(mr.join)(apply),
|
|
18
26
|
|
|
19
27
|
/** @readonly */
|
|
20
|
-
sum:
|
|
28
|
+
sum: apply(mr.sum),
|
|
21
29
|
|
|
22
30
|
/**
|
|
23
31
|
* @readonly
|
|
@@ -31,18 +39,6 @@ module.exports = {
|
|
|
31
39
|
}
|
|
32
40
|
}),
|
|
33
41
|
|
|
34
|
-
/**
|
|
35
|
-
* @readonly
|
|
36
|
-
* @type {<T, R>(f: (value: T) => Promise<R>) => (c: AsyncIterable<T>) => AsyncIterable<R>}
|
|
37
|
-
*/
|
|
38
|
-
asyncMap: f => c => ({
|
|
39
|
-
async *[Symbol.asyncIterator]() {
|
|
40
|
-
for await (const i of c) {
|
|
41
|
-
yield* [f(i)]
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}),
|
|
45
|
-
|
|
46
42
|
/**
|
|
47
43
|
* @readonly
|
|
48
44
|
* @type {<T>(_: (_: T) => boolean) => (_: Iterable<T>) => T|undefined}
|
package/iterable/test.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const i = require('.')
|
|
2
|
+
const lib = require('../lib')
|
|
3
|
+
|
|
4
|
+
{
|
|
5
|
+
const r = i.sum([120, 300, 42])
|
|
6
|
+
if (r !== 462) { throw 'error' }
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
{
|
|
10
|
+
if (i.sum([1, 2]) !== 3) { throw 'error' }
|
|
11
|
+
if (i.sum([1, 2]) !== 3) { throw 'error' }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
{
|
|
15
|
+
const x = Array.from(i.map(a => a ** 2)([1, 2, 3]))
|
|
16
|
+
if (x.length !== 3) { throw 'error' }
|
|
17
|
+
if (x[0] !== 1) { throw 'error' }
|
|
18
|
+
if (x[1] !== 4) { throw 'error' }
|
|
19
|
+
if (x[2] !== 9) { throw 'error' }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
if (i.join('/')([]) !== '') { throw 'error' }
|
|
24
|
+
if (i.join('/')(['a']) !== 'a') { throw 'error' }
|
|
25
|
+
if (i.join('/')(['a', 'b']) !== 'a/b') { throw 'error'}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
{
|
|
29
|
+
if (i.find(x => x === 'c')(['a', 'b', 'c']) !== 'c') { throw 'error' }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
{
|
|
33
|
+
/** @type {(_: string) => string|undefined} */
|
|
34
|
+
const file = _ => 'x'
|
|
35
|
+
/** @type {(_: string) => string|undefined} */
|
|
36
|
+
const x = p => lib.pipe
|
|
37
|
+
(i.map(x => file(x())))
|
|
38
|
+
(i.find(x => x !== undefined))
|
|
39
|
+
([() => p, () => `${p}.js`, () => `${p}/index.js`])
|
|
40
|
+
if (x('index.js') !== 'x') { throw 'error' }
|
|
41
|
+
}
|
package/lib/index.js
CHANGED
|
@@ -23,31 +23,6 @@
|
|
|
23
23
|
/**
|
|
24
24
|
* @template T
|
|
25
25
|
* @typedef {[T]|Continue<T>} Continuation
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/** @type {(_: string) => never} */
|
|
29
|
-
const panic = message => { throw message }
|
|
30
|
-
|
|
31
|
-
/** @type {<A>(_: A) => <B>(_: B) => [A, B]} */
|
|
32
|
-
const tuple2 = a => b => [a, b]
|
|
33
|
-
|
|
34
|
-
// /** @type {<T>(_: (_: string) => T) => (_: Dictionary<T>) => (_: string) => [T, Dictionary<T>]} */
|
|
35
|
-
// const cache = f => d => k => {
|
|
36
|
-
// const set = () => {
|
|
37
|
-
// const r = f(k)
|
|
38
|
-
// return tuple2(r)(d.set(k)(r))
|
|
39
|
-
// }
|
|
40
|
-
// const result = d.get(k)
|
|
41
|
-
// return result !== undefined ? [result, d] : set()
|
|
42
|
-
// }
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* @template T
|
|
46
|
-
* @template R
|
|
47
|
-
* @typedef {{
|
|
48
|
-
* merge: (_: R) => (_: T) => R
|
|
49
|
-
* init: R
|
|
50
|
-
* }} Reduce
|
|
51
26
|
*/
|
|
52
27
|
|
|
53
28
|
/** @type {<I, X>(_: (_: I) => X) => <O>(_: (_: X) => O) => (_: I) => O} */
|
|
@@ -88,47 +63,12 @@ const chain = value => ({
|
|
|
88
63
|
* }} Pipe
|
|
89
64
|
*/
|
|
90
65
|
|
|
91
|
-
/** @type {<I, T>(f: (input: I) => T) => Pipe<I, T>} */
|
|
92
|
-
const pipex = f => ({
|
|
93
|
-
x: g => pipex(pipe(f)(g)),
|
|
94
|
-
f,
|
|
95
|
-
})
|
|
96
|
-
|
|
97
66
|
module.exports = {
|
|
98
67
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
todo: () => panic('not implemented'),
|
|
102
|
-
|
|
103
|
-
/** @type {(_: string) => (_: boolean) => void} */
|
|
104
|
-
panic_if: message => condition => condition ? panic(message) : undefined,
|
|
105
|
-
|
|
106
|
-
/** @type {<T>(_: Continuation<T>) => T} */
|
|
107
|
-
trampoline: continuation => {
|
|
108
|
-
while (true) {
|
|
109
|
-
if (typeof continuation !== 'function') {
|
|
110
|
-
return continuation[0]
|
|
111
|
-
}
|
|
112
|
-
continuation = continuation()
|
|
113
|
-
}
|
|
114
|
-
},
|
|
115
|
-
|
|
116
|
-
/** @type {(s: string) => Reduce<string, string>} */
|
|
117
|
-
join: s => ({ merge: a => i => a === '' ? i : a + s + i, init: ''}),
|
|
68
|
+
todo: () => { throw 'not implemented' },
|
|
118
69
|
|
|
119
70
|
pipe,
|
|
120
71
|
|
|
121
|
-
pipex,
|
|
122
|
-
|
|
123
|
-
/** @type {Reduce<number, number>} */
|
|
124
|
-
sum: { merge: a => i => a + i, init: 0 },
|
|
125
|
-
|
|
126
|
-
/** @type {<I, X>(f: (init: I) => X) => <O>(reduce: Reduce<X, O>) => Reduce<I, O>} */
|
|
127
|
-
map: f => ({merge, init}) => ({
|
|
128
|
-
merge: pipe(merge)(pipe(f)),
|
|
129
|
-
init,
|
|
130
|
-
}),
|
|
131
|
-
|
|
132
72
|
last,
|
|
133
73
|
|
|
134
74
|
optionMap,
|
package/lib/test.js
CHANGED
package/{lib/map → map}/index.js
RENAMED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
const { optionMap } = require("
|
|
2
|
-
const { getVisitor, setVisitor, values } = require("../
|
|
1
|
+
const { optionMap } = require("../lib")
|
|
2
|
+
const { getVisitor, setVisitor, values } = require("../btree")
|
|
3
3
|
|
|
4
|
-
/** @typedef {import("../
|
|
4
|
+
/** @typedef {import("../cmp").Sign} Sign */
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* @template T
|
|
8
|
-
* @typedef {import("../
|
|
8
|
+
* @typedef {import("../btree").Leaf1<T>} Leaf1
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @template T
|
|
13
|
-
* @typedef {import("../
|
|
13
|
+
* @typedef {import("../btree").TNode<T>} TNode
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
/**
|
|
17
17
|
* @template T
|
|
18
|
-
* @typedef {import("../
|
|
18
|
+
* @typedef {import("../cmp").Cmp<T>} Cmp
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
/**
|
|
@@ -57,7 +57,7 @@ const create = root => ({
|
|
|
57
57
|
* readonly root: undefined
|
|
58
58
|
* }}
|
|
59
59
|
*/
|
|
60
|
-
const
|
|
60
|
+
const empty = {
|
|
61
61
|
get: () => undefined,
|
|
62
62
|
set: name => value => create([[name, value]]),
|
|
63
63
|
entries: () => [],
|
|
@@ -66,5 +66,5 @@ const map = {
|
|
|
66
66
|
|
|
67
67
|
module.exports = {
|
|
68
68
|
/** @readonly */
|
|
69
|
-
|
|
69
|
+
empty,
|
|
70
70
|
}
|
package/{lib/map → map}/test.js
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const lib = require('
|
|
1
|
+
const { empty } = require('.')
|
|
2
|
+
const lib = require('../lib')
|
|
3
3
|
|
|
4
4
|
{
|
|
5
|
-
let m =
|
|
5
|
+
let m = empty.set('a')(1)
|
|
6
6
|
|
|
7
7
|
if (m.get('a') !== 1) { throw 'error' }
|
|
8
8
|
if (m.get('b') !== undefined) { throw 'error' }
|
|
@@ -41,19 +41,18 @@ const lib = require('..')
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
{
|
|
44
|
-
const m =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
const m = empty.set('x')(12).set('y')(44)
|
|
45
|
+
if (m.get('x') !== 12) { throw 'error' }
|
|
46
|
+
if (m.get('y') !== 44) { throw 'error' }
|
|
47
|
+
if (m.get('a') !== undefined) { throw 'error' }
|
|
48
48
|
const entries = Array.from(m.entries())
|
|
49
|
-
|
|
49
|
+
if (entries.length !== 2) { throw 'error' }
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
|
|
53
52
|
{
|
|
54
53
|
/** @type {import('.').Map<number>} */
|
|
55
|
-
let m =
|
|
56
|
-
for (let i = 0; i <
|
|
54
|
+
let m = empty
|
|
55
|
+
for (let i = 0; i < 100_000; ++i) {
|
|
57
56
|
m = m.set((i*i).toString())(i)
|
|
58
57
|
/*
|
|
59
58
|
console.log()
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const { pipe } = require('../lib')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template I
|
|
5
|
+
* @template S
|
|
6
|
+
* @template O
|
|
7
|
+
* @typedef {{
|
|
8
|
+
* readonly reduce: (state: S) => (value: I) => S
|
|
9
|
+
* readonly result: (state: S) => O
|
|
10
|
+
* readonly init: S
|
|
11
|
+
* }} Operation
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** @type {<I, T>(mapFn: (value: I) => T) => <S, O>(op: Operation<T, S, O>) => Operation<I, S, O>} */
|
|
15
|
+
const map = mapFn => ({ reduce, result, init}) => ({
|
|
16
|
+
reduce: pipe(reduce)(pipe(mapFn)),
|
|
17
|
+
result,
|
|
18
|
+
init,
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
/** @type {(separator: string) => Operation<string, string|undefined, string>} */
|
|
22
|
+
const join = separator => ({
|
|
23
|
+
reduce: s => i => s === undefined ? i : `${s}${separator}${i}`,
|
|
24
|
+
init: undefined,
|
|
25
|
+
result: s => s === undefined ? '' : s
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
/** @type {Operation<number, number, number>} */
|
|
29
|
+
const sum = {
|
|
30
|
+
reduce: a => i => a + i,
|
|
31
|
+
result: a => a,
|
|
32
|
+
init: 0,
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
/** @readonly */
|
|
37
|
+
map,
|
|
38
|
+
/** @readonly */
|
|
39
|
+
join,
|
|
40
|
+
/** @readonly */
|
|
41
|
+
sum,
|
|
42
|
+
}
|
package/module-manager/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const lib = require('../lib')
|
|
2
|
-
const iter = require('../
|
|
2
|
+
const iter = require('../iterable')
|
|
3
|
+
const mr = require('../map-reduce')
|
|
3
4
|
|
|
4
5
|
/** @typedef {(_: string) => string|undefined} ReadFile */
|
|
5
6
|
|
|
@@ -28,9 +29,9 @@ const iter = require('../lib/iterable')
|
|
|
28
29
|
|
|
29
30
|
/** @typedef {(_: string) => undefined|Package|Dependencies} Dependencies */
|
|
30
31
|
|
|
31
|
-
/** @type {
|
|
32
|
+
/** @type {mr.Operation<string, undefined|string[], undefined|string[]>} */
|
|
32
33
|
const pathNormReduce = {
|
|
33
|
-
|
|
34
|
+
reduce: path => item =>
|
|
34
35
|
path === undefined ?
|
|
35
36
|
undefined :
|
|
36
37
|
['', '.'].includes(item) ?
|
|
@@ -38,13 +39,14 @@ const pathNormReduce = {
|
|
|
38
39
|
item === '..' ?
|
|
39
40
|
lib.head(path) :
|
|
40
41
|
[...path, item],
|
|
41
|
-
init: []
|
|
42
|
+
init: [],
|
|
43
|
+
result: s => s,
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
/** @type {(_: string[]) => boolean} */
|
|
45
47
|
const isRelative = localId => ['.', '..'].includes(localId[0])
|
|
46
48
|
|
|
47
|
-
const pathNorm = iter.
|
|
49
|
+
const pathNorm = iter.apply(pathNormReduce)
|
|
48
50
|
|
|
49
51
|
/** @type {(_: Package) => (_: string[]) => Module|undefined} */
|
|
50
52
|
const internal = pack => {
|
|
@@ -91,8 +93,12 @@ const getModule = ({pack, local}) => path => {
|
|
|
91
93
|
const moduleId = module => [...module.location.pack.id, ...module.location.local, module.fileName].join('/')
|
|
92
94
|
|
|
93
95
|
module.exports = {
|
|
96
|
+
/** @readonly */
|
|
94
97
|
isRelative,
|
|
98
|
+
/** @readonly */
|
|
95
99
|
pathNorm,
|
|
100
|
+
/** @readonly */
|
|
96
101
|
getModule,
|
|
102
|
+
/** @readonly */
|
|
97
103
|
moduleId,
|
|
98
104
|
}
|
package/module-manager/test.js
CHANGED
|
@@ -2,22 +2,19 @@ const i = require('.')
|
|
|
2
2
|
|
|
3
3
|
const lib = require('../lib')
|
|
4
4
|
|
|
5
|
-
{
|
|
6
|
-
if (require('./test0') !== 'test0.js') { throw './test0' }
|
|
7
|
-
if (require('./test0.js') !== 'test0.js') { throw './test0.js'}
|
|
8
|
-
if (require('./test0.js.js') !== 'test0.js.js') { throw './test0.js.js'}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
5
|
require('./node/test')
|
|
12
6
|
|
|
13
7
|
/** @type {<T>(_: T | undefined) => T} */
|
|
14
|
-
const cast = x =>
|
|
8
|
+
const cast = x => {
|
|
9
|
+
if (x === undefined) { throw 'x' }
|
|
10
|
+
return x
|
|
11
|
+
}
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
if (i.isRelative('a/b/c'.split('/'))) { throw 'error '}
|
|
14
|
+
if (!i.isRelative('./a/b/c'.split('/'))) { throw 'error ' }
|
|
15
|
+
if (cast(i.pathNorm('a/../b'.split('/'))).join('/') !== 'b') { throw 'error ' }
|
|
16
|
+
if (cast(i.pathNorm('a/../b/../c'.split('/'))).join('/') !== 'c') { throw 'error ' }
|
|
17
|
+
if (cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('/') !== 'b/d') { throw 'error ' }
|
|
21
18
|
|
|
22
19
|
{
|
|
23
20
|
/** @type {i.Package} */
|
|
@@ -41,7 +38,8 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
|
|
|
41
38
|
'index.js': 'b/c ./index.js',
|
|
42
39
|
'x/index.js': 'b/c ./x/index.js',
|
|
43
40
|
}
|
|
44
|
-
|
|
41
|
+
if (['.js', '', 'undefined.js'].includes(path)) { throw '.js' }
|
|
42
|
+
return f[path]
|
|
45
43
|
},
|
|
46
44
|
id: ['c']
|
|
47
45
|
}
|
|
@@ -65,7 +63,8 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
|
|
|
65
63
|
'a/index.js': './a/index.js',
|
|
66
64
|
'a/index.js.js': './a/index.js.js',
|
|
67
65
|
}
|
|
68
|
-
|
|
66
|
+
if (['.js', '', 'undefined.js'].includes(path)) { throw '.js' }
|
|
67
|
+
return f[path]
|
|
69
68
|
},
|
|
70
69
|
id: ['']
|
|
71
70
|
}
|
|
@@ -78,8 +77,8 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
|
|
|
78
77
|
}
|
|
79
78
|
{
|
|
80
79
|
const g = i.getModule({pack, local: []})
|
|
81
|
-
|
|
82
|
-
|
|
80
|
+
if (g('') !== undefined) { throw 'error' }
|
|
81
|
+
if (g('..') !== undefined) { throw 'error' }
|
|
83
82
|
expect(g('.'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
|
|
84
83
|
expect(g('./index'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
|
|
85
84
|
expect(g('./index.js'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
|
|
@@ -87,10 +86,10 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
|
|
|
87
86
|
expect(g('./a'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
|
|
88
87
|
expect(g('./a/index'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
|
|
89
88
|
expect(g('./a/index.js'))({ fileName: 'index.js.js', location: { pack, local: ['a']}, source: './a/index.js'})
|
|
90
|
-
|
|
89
|
+
if (g('./x') !== undefined) { throw 'error' }
|
|
91
90
|
expect(g('a'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
|
|
92
91
|
expect(g('a/index'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
|
|
93
|
-
|
|
92
|
+
if (g('b') !== undefined) { throw 'error' }
|
|
94
93
|
expect(g('b/c'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
|
|
95
94
|
expect(g('b/c/index'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
|
|
96
95
|
expect(g('b/c/index.js'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
|
|
@@ -99,21 +98,21 @@ lib.panic_if('pathNorm')(cast(i.pathNorm('./a/../b/c/..//d/'.split('/'))).join('
|
|
|
99
98
|
}
|
|
100
99
|
{
|
|
101
100
|
const g = i.getModule({pack, local: ['index']})
|
|
102
|
-
|
|
101
|
+
if (g('') !== undefined) { throw 'error' }
|
|
103
102
|
expect(g('..'))({ fileName: 'index.js', location: { pack, local: []}, source: './index.js'})
|
|
104
103
|
expect(g('.'))({ fileName: 'index.js', location: { pack, local: ['index']}, source: './index/index.js'})
|
|
105
104
|
expect(g('./index'))({ fileName: 'index.js', location: { pack, local: ['index']}, source: './index/index.js'})
|
|
106
105
|
expect(g('./index.js'))({ fileName: 'index.js', location: { pack, local: ['index']}, source: './index/index.js'})
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
if (g('./index/') !== undefined) { throw 'error' }
|
|
107
|
+
if (g('./a') !== undefined) { throw 'error' }
|
|
109
108
|
expect(g('../a'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
|
|
110
109
|
expect(g('../a/index'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
|
|
111
110
|
expect(g('../a/index.js'))({ fileName: 'index.js', location: { pack, local: ['a']}, source: './a/index.js'})
|
|
112
111
|
expect(g('../a/index.js.js'))({ fileName: 'index.js.js', location: { pack, local: ['a']}, source: './a/index.js.js'})
|
|
113
|
-
|
|
112
|
+
if (g('./x') !== undefined) { throw 'error' }
|
|
114
113
|
expect(g('a'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
|
|
115
114
|
expect(g('a/index'))({ fileName: 'index.js', location: { pack: a, local: []}, source: 'a ./index.js'})
|
|
116
|
-
|
|
115
|
+
if (g('b') !== undefined) { throw 'error' }
|
|
117
116
|
expect(g('b/c'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
|
|
118
117
|
expect(g('b/c/index'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
|
|
119
118
|
expect(g('b/c/index.js'))({ fileName: 'index.js', location: { pack: c, local: []}, source: 'b/c ./index.js'})
|
package/package.json
CHANGED
package/test.js
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
const lib = require('./lib')
|
|
2
2
|
const i = require('./')
|
|
3
3
|
|
|
4
|
+
require('./async/test')
|
|
4
5
|
require('./module-manager/test')
|
|
5
6
|
require('./lib/test')
|
|
6
7
|
|
|
7
8
|
/** @type {() => never} */
|
|
8
|
-
const assert = () =>
|
|
9
|
+
const assert = () => { throw 'assert' }
|
|
9
10
|
|
|
10
11
|
/** @type {(_: boolean) => void} */
|
|
11
|
-
const assert_if = c =>
|
|
12
|
+
const assert_if = c => { if (c) { throw 'assert_if' } }
|
|
12
13
|
|
|
13
14
|
{
|
|
14
15
|
i.parseModuleUrl('')(
|
package/lib/iterable/test.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
const i = require('.')
|
|
2
|
-
const lib = require('..')
|
|
3
|
-
|
|
4
|
-
{
|
|
5
|
-
const r = i.sum([120, 300, 42])
|
|
6
|
-
lib.panic_if('reduce')(r !== 462)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
{
|
|
10
|
-
lib.panic_if('first sum')(i.sum([1, 2]) !== 3)
|
|
11
|
-
lib.panic_if('second sum')(i.sum([1, 2]) !== 3)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
{
|
|
15
|
-
const x = Array.from(i.map(a => a ** 2)([1, 2, 3]))
|
|
16
|
-
lib.panic_if('map')(x.length !== 3)
|
|
17
|
-
lib.panic_if('map[0]')(x[0] !== 1)
|
|
18
|
-
lib.panic_if('map[1]')(x[1] !== 4)
|
|
19
|
-
lib.panic_if('map[2]')(x[2] !== 9)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
{
|
|
23
|
-
lib.panic_if('join')(i.join('/')([]) !== '')
|
|
24
|
-
lib.panic_if('join')(i.join('/')(['a']) !== 'a')
|
|
25
|
-
lib.panic_if('join')(i.join('/')(['a', 'b']) !== 'a/b')
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
{
|
|
29
|
-
lib.panic_if('find')(i.find(x => x === 'c')(['a', 'b', 'c']) !== 'c')
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
{
|
|
33
|
-
/** @type {(_: string) => string|undefined} */
|
|
34
|
-
const file = _ => 'x'
|
|
35
|
-
/** @type {(_: string) => string|undefined} */
|
|
36
|
-
const x = p => lib.pipe
|
|
37
|
-
(i.map(x => file(x())))
|
|
38
|
-
(i.find(x => x !== undefined))
|
|
39
|
-
([() => p, () => `${p}.js`, () => `${p}/index.js`])
|
|
40
|
-
lib.panic_if('map.find')(x('index.js') !== 'x')
|
|
41
|
-
}
|
package/lib/tree/lazy.js
DELETED
package/module-manager/test0.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = 'test0.js'
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
module.exports = 'test0.js.js'
|