functionalscript 0.0.186 → 0.0.187

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/btree/test.js CHANGED
@@ -24,8 +24,6 @@ const test = () => {
24
24
  /** @type {import('../sequence').Result<string>} */
25
25
  let result = list.next(valuesList(node))
26
26
  while (result !== undefined) {
27
- const t = result[0]
28
- console.log(t)
29
27
  result = list.next(result[1])
30
28
  }
31
29
  }
package/json/index.js ADDED
@@ -0,0 +1,88 @@
1
+ const seq = require('../sequence')
2
+ const map = require('../map')
3
+ const op = require('../sequence/operator')
4
+ const { todo } = require('../dev')
5
+
6
+ /**
7
+ * @typedef {{
8
+ * readonly [k in string]: Json
9
+ * }} Object
10
+ */
11
+
12
+ /** @typedef {readonly Json[]} Array */
13
+
14
+ /** @typedef {Object|boolean|string|number|null|Array} Json */
15
+
16
+ /** @type {(value: Json) => (path: readonly string[]) => (src: Json|undefined) => Json} */
17
+ const addProperty = value => {
18
+ /** @type {(path: seq.Sequence<string>) => (src: Json|undefined) => Json} */
19
+ const f = path => src => {
20
+ const result = seq.next(path)
21
+ if (result === undefined) { return value }
22
+ const srcObject = (src === undefined || src === null || typeof src !== 'object' || src instanceof Array) ? {} : src
23
+ const [name, tail] = result
24
+ return { ...srcObject, [name]: f(tail)(srcObject[name]) }
25
+ }
26
+ return path => f(seq.fromArray(path))
27
+ }
28
+
29
+ /** @type {(kv: readonly[string, seq.Sequence<string>]) => seq.Sequence<string>} */
30
+ const property = ([k, v]) => {
31
+ let r = seq.one(JSON.stringify(k))
32
+ r = seq.concat(r)(seq.one(':'))
33
+ return seq.concat(r)(v)
34
+ }
35
+
36
+ /** @type {op.Scan<seq.Sequence<string>, seq.Sequence<string>>} */
37
+ const commaValue = a => [seq.concat(seq.one(','))(a), commaValue]
38
+
39
+ /** @type {op.Scan<seq.Sequence<string>, seq.Sequence<string>>} */
40
+ const joinScan = value => [value, commaValue]
41
+
42
+ /** @type {seq.SequenceMap<seq.Sequence<string>, seq.Sequence<string>>} */
43
+ const join = seq.scan(joinScan)
44
+
45
+ /** @type {(object: Object) => seq.Sequence<string>} */
46
+ const objectStringify = object => {
47
+ /** @type {map.Map<seq.Sequence<string>>} */
48
+ let m = map.empty
49
+ for (const [k, v] of Object.entries(object)) {
50
+ m = m.set(k)(stringSeq(v))
51
+ }
52
+ const properties = join(seq.map(property)(m.entries))
53
+ const result = seq.concat(seq.one('{'))(seq.flat(properties))
54
+ return seq.concat(result)(seq.one('}'))
55
+ }
56
+
57
+ /** @type {(array: Array) => seq.Sequence<string>} */
58
+ const arrayStringify = array => {
59
+ let a = seq.flat(join(seq.map(stringSeq)(seq.fromArray(array))))
60
+ const s = seq.concat(seq.one('['))(a)
61
+ return seq.concat(s)(seq.one(']'))
62
+ }
63
+
64
+ /** @type {(value: Json) => seq.Sequence<string>} */
65
+ const stringSeq = value => {
66
+ const x = typeof value
67
+ switch (typeof value) {
68
+ case 'boolean': { return seq.one(value ? "true" : "false") }
69
+ // Note: we shouldn't use JSON.stringify since it has non determenistic behavior.
70
+ // In particular: property order could be different.
71
+ case 'number': case 'string': { return seq.one(JSON.stringify(value)) }
72
+ default: {
73
+ if (value === null) { return seq.one("null") }
74
+ if (value instanceof Array) { return arrayStringify(value) }
75
+ return objectStringify(value)
76
+ }
77
+ }
78
+ }
79
+
80
+ /** @type {(value: Json) => string} */
81
+ const stringify = value => seq.join('')(stringSeq(value))
82
+
83
+ module.exports = {
84
+ /** @readonly */
85
+ addProperty,
86
+ /** @readonly */
87
+ stringify,
88
+ }
package/json/test.js ADDED
@@ -0,0 +1,13 @@
1
+ const json = require('.')
2
+
3
+ if (json.addProperty("Hello")([])({}) !== "Hello") { throw 'error' }
4
+
5
+ {
6
+ const x = json.stringify(json.addProperty("Hello")(['a'])({}))
7
+ if (x !== '{"a":"Hello"}') { throw x }
8
+ }
9
+
10
+ {
11
+ const x = json.stringify(json.addProperty("Hello")(['a'])({c:[],b:12}))
12
+ if (x !== '{"a":"Hello","b":12,"c":[]}') { throw x }
13
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functionalscript",
3
- "version": "0.0.186",
3
+ "version": "0.0.187",
4
4
  "description": "FunctionalScript is a functional subset of JavaScript",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/sequence/test.js CHANGED
@@ -1,5 +1,6 @@
1
1
  const seq = require('.')
2
2
  const { sum } = require('./operator')
3
+ const op = require('./operator')
3
4
 
4
5
  /** @type {<T>(input: seq.Sequence<T>) => void} */
5
6
  const print = input => {
@@ -40,4 +41,9 @@ const print = input => {
40
41
  const r = seq.next(x)
41
42
  // print(x)
42
43
  }
43
- }
44
+ }
45
+
46
+ {
47
+ const x = seq.join(':')(seq.fromArray(["1", "2", "3", "4", "5", "6"]))
48
+ if (x !== "1:2:3:4:5:6") { throw x }
49
+ }
package/test.js CHANGED
@@ -5,6 +5,7 @@ require('./btree/test')
5
5
  require('./sequence/iterable/test')
6
6
  require('./sequence/asyncIterable/test')
7
7
  require('./module-manager/test')
8
+ require('./json/test')
8
9
 
9
10
  /** @type {() => never} */
10
11
  const assert = () => { throw 'assert' }