functionalscript 0.0.237 → 0.0.241
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/.github/workflows/node.js.yml +0 -2
- package/commonjs/README.md +55 -0
- package/commonjs/module/index.js +35 -0
- package/commonjs/package/dependencies/index.js +0 -38
- package/commonjs/package/dependencies/test.js +0 -25
- package/commonjs/package/index.js +8 -1
- package/commonjs/package/test.js +5 -5
- package/commonjs/path/index.js +55 -5
- package/commonjs/path/test.js +33 -16
- package/commonjs/run/index.js +1 -1
- package/io/commonjs/index.js +5 -5
- package/io/commonjs/test.js +1 -1
- package/io/nodejs/version/index.js +1 -6
- package/package.json +9 -2
- package/tsconfig.json +1 -1
- package/types/btree/index.js +21 -23
- package/types/map/index.js +38 -44
- package/types/map/test.js +35 -34
- package/types/object/index.js +2 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Common.js
|
|
2
|
+
|
|
3
|
+
```ts
|
|
4
|
+
// package/index.js
|
|
5
|
+
|
|
6
|
+
type PackageGet = (packageId: string) => Package | undefined
|
|
7
|
+
type Package = {
|
|
8
|
+
// returns a global package id.
|
|
9
|
+
readonly dependency: (localPackageId: string) => string | undefined
|
|
10
|
+
// returns source of the file.
|
|
11
|
+
readonly file: (localFileId: string) => string | undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// module/index.js
|
|
15
|
+
|
|
16
|
+
type ModuleMapInterface<M> = {
|
|
17
|
+
readonly at: (moduleId: string) => (moduleMap: M) => ModuleState | undefined
|
|
18
|
+
readonly insert: (moduleId: string) => (moduleState: ModuleState) => (moduleMap: M) => M
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ModuleState = readonly['ok', Module] | readonly['error', ModuleError] | readonly['building']
|
|
22
|
+
|
|
23
|
+
type Module = {
|
|
24
|
+
readonly exports: unknown
|
|
25
|
+
readonly requireMap: object.Map<string>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
type ModuleError = 'file not found' | 'compile error' | 'runtime error' | 'circular reference'
|
|
29
|
+
|
|
30
|
+
type ModuleId = {
|
|
31
|
+
readonly packageId: string,
|
|
32
|
+
readonly path: readonly string[],
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const moduleIdToString: (moduleId: ModuleId) => string;
|
|
36
|
+
|
|
37
|
+
// build/index.js
|
|
38
|
+
|
|
39
|
+
type BuildConfig<M> = {
|
|
40
|
+
readonly packageGet: PackageGet
|
|
41
|
+
readonly moduleMapInterface: ModuleMapInterface<M>
|
|
42
|
+
readonly moduleId: ModuleId
|
|
43
|
+
readonly moduleMap: M // mutable
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type BuildState<M> = {
|
|
47
|
+
readonly packageGet: PackageGet
|
|
48
|
+
readonly moduleMapInterface: ModuleMapInterface<M>
|
|
49
|
+
readonly moduleId: ModuleId
|
|
50
|
+
readonly moduleMap: M // mutable
|
|
51
|
+
readonly ModuleRequireMap: map.Map<string> // mutable
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const getOrBuild: <M>(buildConfig: BuildConfig<M>) => readonly[ModuleState, M];
|
|
55
|
+
```
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const object = require('../../types/object')
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @template M
|
|
5
|
+
* @typedef {{
|
|
6
|
+
* readonly at: (moduleId: string) => (moduleMap: M) => ModuleState | undefined
|
|
7
|
+
* readonly insert: (moduleId: string) => (moduleState: ModuleState) => (moduleMap: M) => M
|
|
8
|
+
* }} ModuleMapInterface
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @typedef {|
|
|
13
|
+
* readonly['ok', Module] |
|
|
14
|
+
* readonly['error', ModuleError] |
|
|
15
|
+
* readonly['building']
|
|
16
|
+
* } ModuleState
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @typedef {{
|
|
21
|
+
* readonly exports: unknown
|
|
22
|
+
* readonly requireMap: object.Map<string>
|
|
23
|
+
* }} Module
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @typedef {|
|
|
28
|
+
* 'file not found' |
|
|
29
|
+
* 'compile error' |
|
|
30
|
+
* 'runtime error' |
|
|
31
|
+
* 'circular reference'
|
|
32
|
+
* } ModuleError
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
module.exports = {}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
const { todo } = require('../../../dev')
|
|
2
1
|
const json = require('../../../json')
|
|
3
|
-
const { isObject } = json
|
|
4
2
|
const seq = require('../../../types/sequence')
|
|
5
|
-
const path = require('../../path')
|
|
6
|
-
const { at } = require('../../../types/object')
|
|
7
3
|
|
|
8
4
|
/** @typedef {readonly[string, string]} DependencyJson */
|
|
9
5
|
|
|
@@ -21,41 +17,7 @@ const isDependenciesJson = j => {
|
|
|
21
17
|
return seq.every(seq.map(isDependencyJson)(Object.entries(j)))
|
|
22
18
|
}
|
|
23
19
|
|
|
24
|
-
/** @typedef {readonly[string, seq.Sequence<string>]} IdPath */
|
|
25
|
-
|
|
26
|
-
/** @type {(prior: readonly[string|undefined, seq.Sequence<string>]) => seq.Thunk<IdPath>} */
|
|
27
|
-
const variants = prior => () => {
|
|
28
|
-
const [a, b] = prior
|
|
29
|
-
const r = seq.next(b)
|
|
30
|
-
if (r === undefined) { return undefined }
|
|
31
|
-
const { first, tail } = r
|
|
32
|
-
/** @type {IdPath} */
|
|
33
|
-
const n = [a === undefined ? first : `${a}/${first}`, tail]
|
|
34
|
-
return { first: n, tail: variants(n) }
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** @type {(d: DependencyMapJson) => (p: IdPath) => IdPath|undefined} */
|
|
38
|
-
const mapDependency = d => ([external, internal]) => {
|
|
39
|
-
const id = at(external)(d)
|
|
40
|
-
if (id === undefined) { return undefined }
|
|
41
|
-
return [id, internal]
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** @typedef {readonly[string, string]} GlobalPath */
|
|
45
|
-
|
|
46
|
-
/** @type {(d: DependenciesJson) => (p: path.Items) => GlobalPath|undefined} */
|
|
47
|
-
const idPath = d => p => {
|
|
48
|
-
if (d === undefined) { return undefined }
|
|
49
|
-
const v = variants([undefined, p])
|
|
50
|
-
const valid = seq.first(undefined)(seq.filterMap(mapDependency(d))(v))
|
|
51
|
-
if (valid === undefined) { return undefined }
|
|
52
|
-
const [packId, localId] = valid
|
|
53
|
-
return [packId, seq.join('/')(localId)]
|
|
54
|
-
}
|
|
55
|
-
|
|
56
20
|
module.exports = {
|
|
57
21
|
/** @readonly */
|
|
58
22
|
isDependenciesJson,
|
|
59
|
-
/** @readonly */
|
|
60
|
-
idPath,
|
|
61
23
|
}
|
|
@@ -10,28 +10,3 @@ const seq = require('../../../types/sequence')
|
|
|
10
10
|
if (!_.isDependenciesJson({'a':'b'})) { throw 'error' }
|
|
11
11
|
if (_.isDependenciesJson({ 'a': 12 })) { throw 'error' }
|
|
12
12
|
}
|
|
13
|
-
|
|
14
|
-
/** @type {(g: _.GlobalPath|undefined) => string} */
|
|
15
|
-
const stringify = g => {
|
|
16
|
-
if (g === undefined) { throw g }
|
|
17
|
-
return json.stringify(sort)(g)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
{
|
|
21
|
-
if (_.idPath(undefined)(['a', 'b']) !== undefined) { throw 'error' }
|
|
22
|
-
if (_.idPath({})(['b']) !== undefined) { throw 'error' }
|
|
23
|
-
if (_.idPath({b:'x'})(['d']) !== undefined) { throw 'error'}
|
|
24
|
-
{
|
|
25
|
-
const result = stringify(_.idPath({ b: 'x' })(['b']))
|
|
26
|
-
if (result !== '["x",""]') { throw result }
|
|
27
|
-
}
|
|
28
|
-
if (_.idPath({ 'b/r': 'x' })(['b']) !== undefined) { throw 'error'}
|
|
29
|
-
{
|
|
30
|
-
const result = stringify(_.idPath({ 'b/r': 'x' })(['b', 'r']))
|
|
31
|
-
if (result !== '["x",""]') { throw result }
|
|
32
|
-
}
|
|
33
|
-
{
|
|
34
|
-
const result = stringify(_.idPath({ 'b/r': 'x' })(['b', 'r', 'd', 't']))
|
|
35
|
-
if (result !== '["x","d/t"]') { throw result }
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
const json = require('../../json')
|
|
2
2
|
const dep = require('./dependencies')
|
|
3
|
+
const object = require('../../types/object')
|
|
4
|
+
const run = require('../run')
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* @typedef {{
|
|
8
|
+
* readonly name: string
|
|
6
9
|
* readonly version: string
|
|
7
10
|
* readonly dependencies?: dep.DependenciesJson
|
|
8
11
|
* }} PackageJson
|
|
@@ -11,6 +14,7 @@ const dep = require('./dependencies')
|
|
|
11
14
|
/** @type {(j: json.Unknown) => j is PackageJson} */
|
|
12
15
|
const isPackageJson = j => {
|
|
13
16
|
if (!json.isObject(j)) { return false }
|
|
17
|
+
if (typeof j.name !== 'string') { return false }
|
|
14
18
|
if (typeof j.version !== 'string') { return false }
|
|
15
19
|
if (!dep.isDependenciesJson(j.dependencies)) { return false }
|
|
16
20
|
return true
|
|
@@ -18,10 +22,13 @@ const isPackageJson = j => {
|
|
|
18
22
|
|
|
19
23
|
/**
|
|
20
24
|
* @typedef {{
|
|
21
|
-
* readonly
|
|
25
|
+
* readonly dependency: (localPackageId: string) => string | undefined
|
|
26
|
+
* readonly file: (localFileId: string) => string | undefined
|
|
22
27
|
* }} Package
|
|
23
28
|
*/
|
|
24
29
|
|
|
30
|
+
/** @typedef {(packageId: string) => Package | undefined} PackageGet */
|
|
31
|
+
|
|
25
32
|
module.exports = {
|
|
26
33
|
/** @readonly */
|
|
27
34
|
isPackageJson,
|
package/commonjs/package/test.js
CHANGED
|
@@ -5,12 +5,12 @@ require('./dependencies/test')
|
|
|
5
5
|
{
|
|
6
6
|
if (_.isPackageJson(null)) { throw 'error' }
|
|
7
7
|
if (_.isPackageJson({})) { throw 'error' }
|
|
8
|
-
if (_.isPackageJson({version:12})) { throw 'error' }
|
|
9
|
-
if (!_.isPackageJson({version:"12"})) { throw 'error' }
|
|
8
|
+
if (_.isPackageJson({name:'x',version:12})) { throw 'error' }
|
|
9
|
+
if (!_.isPackageJson({name:'x',version:"12"})) { throw 'error' }
|
|
10
10
|
if (_.isPackageJson({version:"",dependencies:[]})) { throw 'error' }
|
|
11
|
-
if (!_.isPackageJson({ version: "", dependencies: {} })) { throw 'error' }
|
|
12
|
-
if (_.isPackageJson({ version: "", dependencies: { x: 12} })) { throw 'error' }
|
|
13
|
-
if (!_.isPackageJson({ version: "", dependencies: { x: "12" } })) { throw 'error' }
|
|
11
|
+
if (!_.isPackageJson({name:'a', version: "", dependencies: {} })) { throw 'error' }
|
|
12
|
+
if (_.isPackageJson({name:'b', version: "", dependencies: { x: 12} })) { throw 'error' }
|
|
13
|
+
if (!_.isPackageJson({name:'c', version: "", dependencies: { x: "12" } })) { throw 'error' }
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
module.exports = {}
|
package/commonjs/path/index.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
const seq = require("../../types/sequence")
|
|
2
2
|
const option = require("../../types/option")
|
|
3
3
|
const { compose } = require("../../types/function")
|
|
4
|
+
const dep = require("../package/dependencies")
|
|
5
|
+
const { at } = require("../../types/object")
|
|
6
|
+
const pack = require("../package")
|
|
4
7
|
|
|
5
8
|
/** @typedef {readonly string[]} Items */
|
|
6
9
|
|
|
@@ -9,7 +12,7 @@ const { compose } = require("../../types/function")
|
|
|
9
12
|
* readonly external: boolean
|
|
10
13
|
* readonly dir: boolean
|
|
11
14
|
* readonly items: Items
|
|
12
|
-
* }}
|
|
15
|
+
* }} LocalPath
|
|
13
16
|
*/
|
|
14
17
|
|
|
15
18
|
/** @type {(path: string) => readonly string[]} */
|
|
@@ -34,8 +37,8 @@ const normItemsOp = prior => item => {
|
|
|
34
37
|
/** @type {(items: seq.Sequence<string>) => seq.Sequence<string>|undefined} */
|
|
35
38
|
const normItems = compose(seq.reduce(normItemsOp)([]))(option.map(seq.reverse))
|
|
36
39
|
|
|
37
|
-
/** @type {(local: string) => (path: string) =>
|
|
38
|
-
const
|
|
40
|
+
/** @type {(local: string) => (path: string) => LocalPath|undefined} */
|
|
41
|
+
const parseLocal = local => {
|
|
39
42
|
/** @type {(path: string) => readonly[boolean, seq.Sequence<string>]} */
|
|
40
43
|
const fSeq = path => {
|
|
41
44
|
const pathSeq = split(path)
|
|
@@ -44,7 +47,7 @@ const parse = local => {
|
|
|
44
47
|
default: { return [true, pathSeq] }
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
|
-
/** @type {(path: string) =>
|
|
50
|
+
/** @type {(path: string) => LocalPath|undefined} */
|
|
48
51
|
const f = path => {
|
|
49
52
|
const [external, items] = fSeq(path)
|
|
50
53
|
const n = normItems(items)
|
|
@@ -58,9 +61,56 @@ const parse = local => {
|
|
|
58
61
|
return f
|
|
59
62
|
}
|
|
60
63
|
|
|
64
|
+
/** @typedef {readonly[string, seq.Sequence<string>]} IdPath */
|
|
65
|
+
|
|
66
|
+
/** @type {(prior: readonly[string|undefined, seq.Sequence<string>]) => seq.Thunk<IdPath>} */
|
|
67
|
+
const variants = prior => () => {
|
|
68
|
+
const [a, b] = prior
|
|
69
|
+
const r = seq.next(b)
|
|
70
|
+
if (r === undefined) { return undefined }
|
|
71
|
+
const { first, tail } = r
|
|
72
|
+
/** @type {IdPath} */
|
|
73
|
+
const n = [a === undefined ? first : `${a}/${first}`, tail]
|
|
74
|
+
return { first: n, tail: variants(n) }
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** @type {(d: dep.DependencyMapJson) => (p: IdPath) => IdPath|undefined} */
|
|
78
|
+
const mapDependency = d => ([external, internal]) => {
|
|
79
|
+
const id = at(external)(d)
|
|
80
|
+
return id === undefined ? undefined : [id, internal]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* @typedef {{
|
|
85
|
+
* readonly name: string,
|
|
86
|
+
* readonly items: Items,
|
|
87
|
+
* readonly dir: boolean,
|
|
88
|
+
* }} Path
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
/** @type {(d: dep.DependenciesJson) => (dir: boolean) => (items: seq.Sequence<string>) => Path|undefined} */
|
|
92
|
+
const parseGlobal = d => dir => items => {
|
|
93
|
+
if (d === undefined) { return undefined }
|
|
94
|
+
const v = variants([undefined, items])
|
|
95
|
+
const r = seq.first(undefined)(seq.filterMap(mapDependency(d))(v))
|
|
96
|
+
if (r === undefined) { return undefined }
|
|
97
|
+
return { name: r[0], items: seq.toArray(r[1]), dir }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** @type {(name: string) => (dependencies: dep.DependenciesJson) => (local: string) => (path: string) => Path|undefined } */
|
|
101
|
+
const parse = name => dependencies => local => path => {
|
|
102
|
+
const parsed = parseLocal(local)(path)
|
|
103
|
+
if (parsed === undefined) { return undefined }
|
|
104
|
+
const {external, dir, items} = parsed
|
|
105
|
+
if (!external) { return { name, items, dir } }
|
|
106
|
+
return parseGlobal(dependencies)(dir)(items)
|
|
107
|
+
}
|
|
108
|
+
|
|
61
109
|
module.exports = {
|
|
62
110
|
/** @readonly */
|
|
63
|
-
|
|
111
|
+
parseLocal,
|
|
112
|
+
/** @readonly */
|
|
113
|
+
parseGlobal,
|
|
64
114
|
/** @readonly */
|
|
65
115
|
parse,
|
|
66
116
|
}
|
package/commonjs/path/test.js
CHANGED
|
@@ -1,47 +1,64 @@
|
|
|
1
1
|
const _ = require('.')
|
|
2
2
|
const json = require('../../json')
|
|
3
|
-
const { identity
|
|
4
|
-
const seq = require('../../types/sequence')
|
|
3
|
+
const { identity } = require('../../types/function')
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
/** @type {(g: json.Unknown|undefined) => string} */
|
|
6
|
+
const stringify = g => {
|
|
7
|
+
if (g === undefined) { throw g }
|
|
8
|
+
return json.stringify(identity)(g)
|
|
9
|
+
}
|
|
7
10
|
|
|
8
11
|
{
|
|
9
|
-
const
|
|
10
|
-
|
|
12
|
+
const p = { name: '', version: '' }
|
|
13
|
+
const result = _.parseLocal('')('./a')
|
|
11
14
|
if (stringify(result) !== '{"external":false,"dir":false,"items":["a"]}') { throw result }
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
{
|
|
15
|
-
const result = _.
|
|
16
|
-
if (result === undefined) { throw result }
|
|
18
|
+
const result = _.parseLocal('')('./a/')
|
|
17
19
|
if (stringify(result) !== '{"external":false,"dir":true,"items":["a"]}') { throw result }
|
|
18
20
|
}
|
|
19
21
|
|
|
20
22
|
{
|
|
21
|
-
const result = _.
|
|
23
|
+
const result = _.parseLocal('')('..')
|
|
22
24
|
if (result !== undefined) { throw result }
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
{
|
|
26
|
-
const result = _.
|
|
27
|
-
if (result === undefined) { throw result }
|
|
28
|
+
const result = _.parseLocal('a')('')
|
|
28
29
|
if (stringify(result) !== '{"external":true,"dir":false,"items":[]}') { throw result }
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
{
|
|
32
|
-
const result = _.
|
|
33
|
-
if (result === undefined) { throw result }
|
|
33
|
+
const result = _.parseLocal('')('./a/b/.././c')
|
|
34
34
|
if (stringify(result) !== '{"external":false,"dir":false,"items":["a","c"]}') { throw result }
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
{
|
|
38
|
-
const result = _.
|
|
39
|
-
if (result === undefined) { throw result }
|
|
38
|
+
const result = _.parseLocal('x/r')('./a/b/.././c')
|
|
40
39
|
if (stringify(result) !== '{"external":false,"dir":false,"items":["x","r","a","c"]}') { throw result }
|
|
41
40
|
}
|
|
42
41
|
|
|
43
42
|
{
|
|
44
|
-
const result = _.
|
|
45
|
-
if (result === undefined) { throw result }
|
|
43
|
+
const result = _.parseLocal('a')('a/b/.././c')
|
|
46
44
|
if (stringify(result) !== '{"external":true,"dir":false,"items":["a","c"]}') { throw result }
|
|
47
45
|
}
|
|
46
|
+
|
|
47
|
+
{
|
|
48
|
+
if (_.parseGlobal(undefined)(false)(['a', 'b']) !== undefined) { throw 'error' }
|
|
49
|
+
if (_.parseGlobal({})(false)(['b']) !== undefined) { throw 'error' }
|
|
50
|
+
if (_.parseGlobal({ b: 'x' })(false)(['d']) !== undefined) { throw 'error' }
|
|
51
|
+
{
|
|
52
|
+
const result = stringify(_.parseGlobal({ b: 'x' })(false)(['b']))
|
|
53
|
+
if (result !== '["x",""]') { throw result }
|
|
54
|
+
}
|
|
55
|
+
if (_.parseGlobal({ 'b/r': 'x' })(false)(['b']) !== undefined) { throw 'error' }
|
|
56
|
+
{
|
|
57
|
+
const result = stringify(_.parseGlobal({ 'b/r': 'x' })(false)(['b', 'r']))
|
|
58
|
+
if (result !== '["x",""]') { throw result }
|
|
59
|
+
}
|
|
60
|
+
{
|
|
61
|
+
const result = stringify(_.parseGlobal({ 'b/r': 'x' })(false)(['b', 'r', 'd', 't']))
|
|
62
|
+
if (result !== '["x","d/t"]') { throw result }
|
|
63
|
+
}
|
|
64
|
+
}
|
package/commonjs/run/index.js
CHANGED
|
@@ -9,7 +9,7 @@ const result = require('../../types/result')
|
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* @template T
|
|
12
|
-
* @typedef {(
|
|
12
|
+
* @typedef {(path: string) => (prior: T) => ModuleResult<T>} Require
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
/** @typedef {(source: string) => result.Result<Module, unknown>} Compile */
|
package/io/commonjs/index.js
CHANGED
|
@@ -3,11 +3,11 @@ const { unwrap } = require('../../types/result')
|
|
|
3
3
|
const run = require('../../commonjs/run')
|
|
4
4
|
|
|
5
5
|
/** @type {(f: Function) => run.Module} */
|
|
6
|
-
const
|
|
6
|
+
const build = f => immutableRequire => mutableData => {
|
|
7
7
|
/** @type {(path: string) => unknown} */
|
|
8
8
|
const mutableRequire = path => {
|
|
9
|
-
const [result,
|
|
10
|
-
|
|
9
|
+
const [result, data] = immutableRequire(path)(mutableData)
|
|
10
|
+
mutableData = data
|
|
11
11
|
return unwrap(result)
|
|
12
12
|
}
|
|
13
13
|
const result = tryCatch(() => {
|
|
@@ -15,12 +15,12 @@ const createModule = f => req => mutableInfo => {
|
|
|
15
15
|
f(mutableModule, mutableRequire)
|
|
16
16
|
return mutableModule.exports
|
|
17
17
|
})
|
|
18
|
-
return [result,
|
|
18
|
+
return [result, mutableData]
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
/** @type {run.Compile} */
|
|
22
22
|
const compile = source =>
|
|
23
|
-
tryCatch(() =>
|
|
23
|
+
tryCatch(() => build(Function('module', 'require', `"use strict";${source}`)))
|
|
24
24
|
|
|
25
25
|
module.exports = {
|
|
26
26
|
/** @readonly */
|
package/io/commonjs/test.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const cp = require('child_process')
|
|
2
2
|
const fs = require('fs')
|
|
3
|
-
const
|
|
4
|
-
const { isPackageJson } = require('../../../commonjs/package')
|
|
3
|
+
const package_json = require('../../../package.json')
|
|
5
4
|
|
|
6
5
|
const b =cp.execSync('git log --oneline')
|
|
7
6
|
|
|
@@ -11,10 +10,6 @@ const v = `0.0.${r}`
|
|
|
11
10
|
|
|
12
11
|
console.log(`version: ${v}`)
|
|
13
12
|
|
|
14
|
-
const package_json = json.parse(fs.readFileSync('package.json').toString())
|
|
15
|
-
|
|
16
|
-
if (!isPackageJson(package_json)) { throw 'error' }
|
|
17
|
-
|
|
18
13
|
const x = { ...package_json, version: v }
|
|
19
14
|
|
|
20
15
|
fs.writeFileSync('package.json', JSON.stringify(x, null, 2))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "functionalscript",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.241",
|
|
4
4
|
"description": "FunctionalScript is a functional subset of JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,12 +14,19 @@
|
|
|
14
14
|
},
|
|
15
15
|
"author": "Natfoam",
|
|
16
16
|
"license": "Apache-2.0",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"lambda",
|
|
19
|
+
"functional-programming",
|
|
20
|
+
"closure",
|
|
21
|
+
"pure-functional",
|
|
22
|
+
"typescript"
|
|
23
|
+
],
|
|
17
24
|
"bugs": {
|
|
18
25
|
"url": "https://github.com/functionalscript/functionalscript/issues"
|
|
19
26
|
},
|
|
20
27
|
"homepage": "https://github.com/functionalscript/functionalscript#readme",
|
|
21
28
|
"devDependencies": {
|
|
22
|
-
"@types/node": "^16.11.
|
|
29
|
+
"@types/node": "^16.11.12",
|
|
23
30
|
"typescript": "^4.5.2"
|
|
24
31
|
}
|
|
25
32
|
}
|
package/tsconfig.json
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */
|
|
34
34
|
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
|
|
35
35
|
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
36
|
-
|
|
36
|
+
"resolveJsonModule": true, /* Enable importing .json files */
|
|
37
37
|
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
|
|
38
38
|
|
|
39
39
|
/* JavaScript Support */
|
package/types/btree/index.js
CHANGED
|
@@ -129,41 +129,39 @@ const seq = require('../sequence')
|
|
|
129
129
|
const split = ([n0, v1, n2, v3, n4, v5, n6]) => [[n0, v1, n2], v3, [n4, v5, n6]]
|
|
130
130
|
|
|
131
131
|
/**
|
|
132
|
-
* @type {<T>(
|
|
132
|
+
* @type {<T>(extend: (o: Branch3<T>) => Result<T>) =>
|
|
133
133
|
* (replace: (r: Node<T>) => Node<T>) =>
|
|
134
134
|
* (result: Result<T>) =>
|
|
135
135
|
* Result<T>}
|
|
136
136
|
*/
|
|
137
|
-
const merge =
|
|
137
|
+
const merge = extend => replace => result => {
|
|
138
138
|
switch (result[0]) {
|
|
139
139
|
case 'done': { return result }
|
|
140
140
|
case 'replace': { return ['replace', replace(result[1])] }
|
|
141
|
-
default: { return
|
|
141
|
+
default: { return extend(result[1]) }
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
-
/**
|
|
146
|
-
* @type {<T>(overflow: (o: Branch3<T>) => Branch5<T>) =>
|
|
147
|
-
* (replace: (r: Node<T>) => Branch3<T>) =>
|
|
148
|
-
* (result: Result<T>) =>
|
|
149
|
-
* Result<T>}
|
|
150
|
-
*/
|
|
151
|
-
const merge2 = overflow => merge(o => ['replace', overflow(o)])
|
|
152
|
-
|
|
153
|
-
/**
|
|
154
|
-
* @type {<T>(overflow: (o: Branch3<T>) => Branch7<T>) =>
|
|
155
|
-
* (replace: (r: Node<T>) => Branch5<T>) =>
|
|
156
|
-
* (result: Result<T>) =>
|
|
157
|
-
* Result<T>}
|
|
158
|
-
*/
|
|
159
|
-
const merge3 = overflow => merge(o => ['overflow', split(overflow(o))])
|
|
160
|
-
|
|
161
145
|
/** @type {(visitor: Visitor) => <T>(cmp: Cmp<T>) => (init: Lazy<T>) => (node: Node<T>) => Result<T>} */
|
|
162
146
|
const visit = ({ found, notFound }) => cmp => {
|
|
163
147
|
const i3 = index3(cmp)
|
|
164
148
|
const i5 = index5(cmp)
|
|
149
|
+
/** @typedef {typeof cmp extends Cmp<infer T> ? T : never} T */
|
|
150
|
+
/**
|
|
151
|
+
* @type {(extend: (o: Branch3<T>) => Branch5<T>) =>
|
|
152
|
+
* (replace: (r: Node<T>) => Branch3<T>) =>
|
|
153
|
+
* (result: Result<T>) =>
|
|
154
|
+
* Result<T>}
|
|
155
|
+
*/
|
|
156
|
+
const merge2 = extend => merge(o => ['replace', extend(o)])
|
|
157
|
+
/**
|
|
158
|
+
* @type {(extend: (o: Branch3<T>) => Branch7<T>) =>
|
|
159
|
+
* (replace: (r: Node<T>) => Branch5<T>) =>
|
|
160
|
+
* (result: Result<T>) =>
|
|
161
|
+
* Result<T>}
|
|
162
|
+
*/
|
|
163
|
+
const merge3 = extend => merge(o => ['overflow', split(extend(o))])
|
|
165
164
|
return init => {
|
|
166
|
-
/** @typedef {typeof cmp extends Cmp<infer T> ? T : never} T*/
|
|
167
165
|
/** @type {(node: Node<T>) => Result<T>} */
|
|
168
166
|
const f = node => {
|
|
169
167
|
switch (node.length) {
|
|
@@ -188,14 +186,14 @@ const visit = ({ found, notFound }) => cmp => {
|
|
|
188
186
|
switch (i3(v1)) {
|
|
189
187
|
case 0: {
|
|
190
188
|
return merge2
|
|
191
|
-
(
|
|
189
|
+
(e => [...e, v1, n2])
|
|
192
190
|
(r => [r, v1, n2])
|
|
193
191
|
(f(n0))
|
|
194
192
|
}
|
|
195
193
|
case 1: { return found.branch3(init)(node) }
|
|
196
194
|
default: {
|
|
197
195
|
return merge2
|
|
198
|
-
(
|
|
196
|
+
(e => [n0, v1, ...e])
|
|
199
197
|
(r => [n0, v1, r])
|
|
200
198
|
(f(n2))
|
|
201
199
|
}
|
|
@@ -339,7 +337,7 @@ module.exports = {
|
|
|
339
337
|
* @type { <T>(cmp: Cmp<T>) => (node: Node<T>) => T|undefined }
|
|
340
338
|
*/
|
|
341
339
|
getVisitor: cmp => node => {
|
|
342
|
-
const result = visit(getVisitor)(cmp)(() => { throw '' })(node)
|
|
340
|
+
const result = visit(getVisitor)(cmp)(() => { throw 'getVisitor' })(node)
|
|
343
341
|
if (result[0] === 'done') { return result[1] }
|
|
344
342
|
return undefined
|
|
345
343
|
},
|
package/types/map/index.js
CHANGED
|
@@ -1,86 +1,80 @@
|
|
|
1
1
|
const option = require("../option")
|
|
2
|
+
const btree = require('../btree')
|
|
2
3
|
const { getVisitor, setVisitor, values } = require("../btree")
|
|
4
|
+
const compare = require("../function/compare")
|
|
3
5
|
const { cmp } = require("../function/compare")
|
|
4
6
|
const seq = require("../sequence")
|
|
5
7
|
|
|
6
|
-
/** @typedef {
|
|
8
|
+
/** @typedef {compare.Sign} Sign */
|
|
7
9
|
|
|
8
10
|
/**
|
|
9
11
|
* @template T
|
|
10
|
-
* @typedef {
|
|
12
|
+
* @typedef {btree.Leaf1<T>} Leaf1
|
|
11
13
|
*/
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* @template T
|
|
15
|
-
* @typedef {
|
|
17
|
+
* @typedef {btree.Node<T>} TNode
|
|
16
18
|
*/
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
21
|
* @template T
|
|
20
|
-
* @typedef {
|
|
22
|
+
* @typedef {compare.Compare<T>} Cmp
|
|
21
23
|
*/
|
|
22
24
|
|
|
23
25
|
/**
|
|
24
26
|
* @template T
|
|
25
|
-
* @typedef {readonly
|
|
27
|
+
* @typedef {readonly[string, T]} Entry
|
|
26
28
|
*/
|
|
27
29
|
|
|
28
|
-
/**
|
|
30
|
+
/**
|
|
29
31
|
* @template T
|
|
30
|
-
* @typedef {
|
|
31
|
-
* readonly get: (name: string) => T|undefined
|
|
32
|
-
* readonly set: (name: string) => (value: T) => Map<T>
|
|
33
|
-
* readonly entries: seq.Sequence<Entry<T>>
|
|
34
|
-
* readonly root: undefined|TNode<Entry<T>>
|
|
35
|
-
* }} Map
|
|
32
|
+
* @typedef {undefined|TNode<Entry<T>>} Map
|
|
36
33
|
*/
|
|
37
34
|
|
|
38
35
|
/** @type {(a: string) => <T>(b: Entry<T>) => Sign} */
|
|
39
36
|
const keyCmp = a => ([b]) => cmp(a)(b)
|
|
40
37
|
|
|
41
|
-
/** @type {<T>(
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
case 'replace': case 'overflow': { return create(result[1]) }
|
|
48
|
-
default: { throw '' }
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
entries: values(root),
|
|
52
|
-
root,
|
|
53
|
-
})
|
|
38
|
+
/** @type {(name: string) => <T>(map: Map<T>) => T|undefined} */
|
|
39
|
+
const at = name => map => {
|
|
40
|
+
if (map === undefined) { return undefined }
|
|
41
|
+
const result = getVisitor(keyCmp(name))(map)
|
|
42
|
+
return result === undefined ? undefined : result[1]
|
|
43
|
+
}
|
|
54
44
|
|
|
55
|
-
/**
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
set: name => value => create([[name, value]]),
|
|
66
|
-
entries: [],
|
|
67
|
-
root: undefined
|
|
45
|
+
/** @type {(name: string) => <T>(value: T) => (map: Map<T>) => Map<T>} */
|
|
46
|
+
const set = name => value => map => {
|
|
47
|
+
/** @type {Entry<typeof value>} */
|
|
48
|
+
const entry = [name, value]
|
|
49
|
+
if (map === undefined) { return [entry] }
|
|
50
|
+
const result = setVisitor(keyCmp(name))(() => entry)(map)
|
|
51
|
+
switch (result[0]) {
|
|
52
|
+
case 'replace': case 'overflow': { return result[1] }
|
|
53
|
+
default: { throw 'invalid BTree operation' }
|
|
54
|
+
}
|
|
68
55
|
}
|
|
69
56
|
|
|
57
|
+
/** @type {<T>(map: Map<T>) => seq.Sequence<Entry<T>>} */
|
|
58
|
+
const entries = map => map === undefined ? [] : values(map)
|
|
59
|
+
|
|
70
60
|
/** @type {<T>(map: Map<T>) => (entry: Entry<T>) => Map<T>} */
|
|
71
|
-
const
|
|
61
|
+
const setOp = map => ([name, value]) => set(name)(value)(map)
|
|
72
62
|
|
|
73
63
|
/** @type {<T>(entries: seq.Sequence<Entry<T>>) => Map<T>} */
|
|
74
64
|
const fromEntries = entries => {
|
|
75
|
-
/** @typedef {typeof entries extends seq.Sequence<Entry<infer T>> ? T : never} T */
|
|
76
|
-
/** @type {Map<T>} */
|
|
77
|
-
const init = empty
|
|
78
|
-
return seq.reduce(setOperator)(init)(entries)
|
|
65
|
+
/** @typedef {typeof entries extends seq.Sequence<Entry<infer T>> ? T : never} T */
|
|
66
|
+
return seq.reduce(setOp)(/** @type {Map<T>} */(undefined))(entries)
|
|
79
67
|
}
|
|
80
68
|
|
|
81
69
|
module.exports = {
|
|
82
70
|
/** @readonly */
|
|
83
|
-
empty,
|
|
71
|
+
empty: undefined,
|
|
72
|
+
/** @readonly */
|
|
73
|
+
at,
|
|
74
|
+
/** @readonly */
|
|
75
|
+
set,
|
|
76
|
+
/** @readonly */
|
|
77
|
+
entries,
|
|
84
78
|
/** @readonly */
|
|
85
79
|
fromEntries,
|
|
86
80
|
}
|
package/types/map/test.js
CHANGED
|
@@ -1,59 +1,60 @@
|
|
|
1
|
-
const { empty } = require('.')
|
|
2
|
-
const
|
|
1
|
+
const { at, set, empty, entries } = require('.')
|
|
2
|
+
const seq = require('../sequence')
|
|
3
3
|
|
|
4
4
|
{
|
|
5
|
-
let m =
|
|
5
|
+
let m = set('a')(1)(undefined)
|
|
6
6
|
|
|
7
|
-
if (
|
|
8
|
-
if (
|
|
7
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
8
|
+
if (at('b')(m) !== undefined) { throw 'error' }
|
|
9
9
|
|
|
10
|
-
m =
|
|
10
|
+
m = set('b')(2)(m)
|
|
11
11
|
|
|
12
|
-
if (
|
|
13
|
-
if (
|
|
14
|
-
if (
|
|
12
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
13
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
14
|
+
if (at('c')(m) !== undefined) { throw 'error' }
|
|
15
15
|
|
|
16
|
-
m =
|
|
16
|
+
m = set('z')(3)(m)
|
|
17
17
|
|
|
18
|
-
if (
|
|
19
|
-
if (
|
|
20
|
-
if (
|
|
21
|
-
if (
|
|
18
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
19
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
20
|
+
if (at('z')(m) !== 3) { throw 'error' }
|
|
21
|
+
if (at('')(m) !== undefined) { throw 'error' }
|
|
22
22
|
|
|
23
|
-
m =
|
|
23
|
+
m = set('')(4)(m)
|
|
24
24
|
|
|
25
|
-
if (
|
|
26
|
-
if (
|
|
27
|
-
if (
|
|
28
|
-
if (
|
|
29
|
-
if (
|
|
25
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
26
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
27
|
+
if (at('z')(m) !== 3) { throw 'error' }
|
|
28
|
+
if (at('')(m) !== 4) { throw 'error' }
|
|
29
|
+
if (at('Hello world!')(m) !== undefined) { throw 'error' }
|
|
30
30
|
|
|
31
|
-
m =
|
|
31
|
+
m = set('Hello world!')(42)(m)
|
|
32
32
|
|
|
33
|
-
if (
|
|
34
|
-
if (
|
|
35
|
-
if (
|
|
36
|
-
if (
|
|
37
|
-
if (
|
|
38
|
-
if (
|
|
33
|
+
if (at('a')(m) !== 1) { throw 'error' }
|
|
34
|
+
if (at('b')(m) !== 2) { throw 'error' }
|
|
35
|
+
if (at('z')(m) !== 3) { throw 'error' }
|
|
36
|
+
if (at('')(m) !== 4) { throw 'error' }
|
|
37
|
+
if (at('Hello world!')(m) !== 42) { throw 'error' }
|
|
38
|
+
if (at('x')(m) !== undefined) { throw 'error' }
|
|
39
39
|
|
|
40
40
|
// console.log(Array.from(m.entries()))
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
44
|
+
let m = set('x')(12)(undefined)
|
|
45
|
+
m = set('y')(44)(m)
|
|
46
|
+
if (at('x')(m) !== 12) { throw 'error' }
|
|
47
|
+
if (at('y')(m) !== 44) { throw 'error' }
|
|
48
|
+
if (at('a')(m) !== undefined) { throw 'error' }
|
|
49
|
+
const e = seq.toArray(entries(m))
|
|
50
|
+
if (e.length !== 2) { throw 'error' }
|
|
50
51
|
}
|
|
51
52
|
|
|
52
53
|
{
|
|
53
54
|
/** @type {import('.').Map<number>} */
|
|
54
55
|
let m = empty
|
|
55
56
|
for (let i = 0; i < 100_000; ++i) {
|
|
56
|
-
m =
|
|
57
|
+
m = set((i * i).toString())(i)(m)
|
|
57
58
|
/*
|
|
58
59
|
console.log()
|
|
59
60
|
console.log(`# ${i}`)
|
package/types/object/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const seq = require('../sequence')
|
|
2
2
|
const map = require('../map')
|
|
3
|
+
const { compose } = require('../function')
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @template T
|
|
@@ -17,7 +18,7 @@ const map = require('../map')
|
|
|
17
18
|
const at = name => object => Object.getOwnPropertyDescriptor(object, name)?.value
|
|
18
19
|
|
|
19
20
|
/** @type {<T>(entries: seq.Sequence<Entry<T>>) => seq.Sequence<Entry<T>>} */
|
|
20
|
-
const sort = entries => map.fromEntries(entries)
|
|
21
|
+
const sort = entries => map.entries(map.fromEntries(entries))
|
|
21
22
|
|
|
22
23
|
module.exports = {
|
|
23
24
|
/** @readonly */
|