firefly-compiler 0.4.11 → 0.4.12
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/core/HttpClient.ff +3 -0
- package/core/JsValue.ff +0 -3
- package/core/Json.ff +121 -3
- package/lsp/CompletionHandler.ff +7 -7
- package/lsp/Handler.ff +2 -2
- package/lsp/LanguageServer.ff +2 -2
- package/lsp/SymbolHandler.ff +1 -1
- package/lux/Main.ff +11 -12
- package/output/js/ff/core/HttpClient.mjs +8 -0
- package/output/js/ff/core/JsValue.mjs +0 -8
- package/output/js/ff/core/Json.mjs +209 -6
- package/package.json +1 -1
- package/vscode/package.json +1 -1
package/core/HttpClient.ff
CHANGED
|
@@ -78,6 +78,9 @@ extend self: FetchResponse {
|
|
|
78
78
|
readText(): String
|
|
79
79
|
target js async "return await self_.text()"
|
|
80
80
|
|
|
81
|
+
readJson(): Json
|
|
82
|
+
target js async "return await self_.json()"
|
|
83
|
+
|
|
81
84
|
readBuffer(): Buffer
|
|
82
85
|
target js async "return new DataView(await self_.arrayBuffer())"
|
|
83
86
|
|
package/core/JsValue.ff
CHANGED
|
@@ -213,9 +213,6 @@ extend self: JsValue {
|
|
|
213
213
|
target js sync "return new self_(a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_)"
|
|
214
214
|
|
|
215
215
|
|
|
216
|
-
toJson(space: Option[String] = None): String
|
|
217
|
-
target js sync "return JSON.stringify(self_, null, space_.value_)"
|
|
218
|
-
|
|
219
216
|
grabPairs(): List[Pair[String, JsValue]]
|
|
220
217
|
target js sync """
|
|
221
218
|
if(!(self_ instanceof Object)) throw new Error('Expected object, got '+ typeof self_);;
|
package/core/Json.ff
CHANGED
|
@@ -62,13 +62,13 @@ fields(body: ((String, Json) => Unit) => Unit): Json
|
|
|
62
62
|
|
|
63
63
|
extend self: Json {
|
|
64
64
|
|
|
65
|
-
write(
|
|
65
|
+
write(indentation: Option[String] = None): String
|
|
66
66
|
target js sync """
|
|
67
67
|
return JSON.stringify(self_, null, space_.value_);
|
|
68
68
|
"""
|
|
69
69
|
|
|
70
70
|
with[T: JsonLike](field: String, value: T): Json {
|
|
71
|
-
internalWith(field, toJson(value))
|
|
71
|
+
internalWith(self, field, toJson(value))
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
merge(that: Json): Json
|
|
@@ -255,7 +255,7 @@ extend self: Json {
|
|
|
255
255
|
|
|
256
256
|
}
|
|
257
257
|
|
|
258
|
-
internalWith(field: String, json: Json): Json
|
|
258
|
+
internalWith(self: Json, field: String, json: Json): Json
|
|
259
259
|
target js sync """
|
|
260
260
|
if(typeof self_ !== 'object' || self_ === null || Array.isArray(self_)) {
|
|
261
261
|
throw new Error('Not an object: ' + JSON.stringify(self_));
|
|
@@ -323,3 +323,121 @@ instance List[T: JsonLike]: JsonLike {
|
|
|
323
323
|
toJson(value: List[T]): Json {list(value.map(toJson))}
|
|
324
324
|
fromJson(json: Json): Option[List[T]] {fromJson[Array[T]](json).map {_.toList()}}
|
|
325
325
|
}
|
|
326
|
+
|
|
327
|
+
instance StringMap[T: JsonLike]: JsonLike {
|
|
328
|
+
toJson(value: StringMap[T]): Json {
|
|
329
|
+
Json.fields {setField =>
|
|
330
|
+
value.each {key, value => setField(key, toJson(value))}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
fromJson(json: Json): Option[StringMap[T]] {
|
|
334
|
+
if(json.isObject()) {
|
|
335
|
+
let map = StringMap.make()
|
|
336
|
+
mutable convertible = True
|
|
337
|
+
json.eachWhile {key, value =>
|
|
338
|
+
fromJson(value).{
|
|
339
|
+
| None => convertible = False
|
|
340
|
+
| Some(v) => map.set(key, v)
|
|
341
|
+
}
|
|
342
|
+
convertible
|
|
343
|
+
}
|
|
344
|
+
if(convertible) {map}
|
|
345
|
+
}.flatten()
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
instance Json: HasAnyTag {
|
|
351
|
+
anyTag(): AnyTag[Json] {Any.internalAnyTag("ff:core/Json.Json[]")}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
instance Json: Show {
|
|
355
|
+
show(value: Json): String {value.write(Some(" "))}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
instance Json: Equal {
|
|
359
|
+
equals(a: Json, b: Json): Bool {
|
|
360
|
+
internalEquals(a, b)
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
instance Json: Order {
|
|
365
|
+
compare(a: Json, b: Json): Ordering {
|
|
366
|
+
Ordering.fromInt(internalCompare(a, b))
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
instance Json: Serializable {
|
|
371
|
+
serializeUsing(serialization: Serialization, value: Json): Unit {
|
|
372
|
+
Serializable.serializeUsing(serialization, value.write())
|
|
373
|
+
}
|
|
374
|
+
deserializeUsing(serialization: Serialization): Json {
|
|
375
|
+
Json.read(Serializable.deserializeUsing[String](serialization)).grab()
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
internalEquals(a: Json, b: Json): Bool
|
|
381
|
+
target js sync """
|
|
382
|
+
if(a_ === b_) {
|
|
383
|
+
return true;
|
|
384
|
+
} else if(Array.isArray(a_) || Array.isArray(b_)) {
|
|
385
|
+
if(!Array.isArray(a_) || !Array.isArray(b_)) return false;
|
|
386
|
+
if(a_.length !== b_.length) return false;
|
|
387
|
+
for(let i = 0; i < a_.length; i++) {
|
|
388
|
+
if(!internalEquals_(a_[i], b_[i])) return false;
|
|
389
|
+
}
|
|
390
|
+
return true;
|
|
391
|
+
} else if(typeof a_ === 'object' && typeof b_ === 'object' && a_ !== null && b_ !== null) {
|
|
392
|
+
const aKeys = Object.keys(a_);
|
|
393
|
+
const bKeys = Object.keys(b_);
|
|
394
|
+
if(aKeys.length !== bKeys.length) return false;
|
|
395
|
+
for(const key of aKeys) {
|
|
396
|
+
if(!Object.hasOwn(b_, key) || !internalEquals_(a_[key], b_[key])) return false;
|
|
397
|
+
}
|
|
398
|
+
return true;
|
|
399
|
+
} else {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
internalCompare(a: Json, b: Json): Int
|
|
405
|
+
target js sync """
|
|
406
|
+
if(a_ === b_) {
|
|
407
|
+
return 0;
|
|
408
|
+
} else if (a_ === null || b_ === null) {
|
|
409
|
+
return a_ === null ? -1 : 1;
|
|
410
|
+
} else if (typeof a_ === 'boolean' || typeof b_ === 'boolean') {
|
|
411
|
+
if(typeof b_ !== 'boolean') return -1;
|
|
412
|
+
if(typeof a_ !== 'boolean') return 1;
|
|
413
|
+
return a_ < b_ ? -1 : 1;
|
|
414
|
+
} else if (typeof a_ === 'number' || typeof b_ === 'number') {
|
|
415
|
+
if(typeof b_ !== 'number') return -1;
|
|
416
|
+
if(typeof a_ !== 'number') return 1;
|
|
417
|
+
if(isNaB(a_)) return isNaB(b_) ? 0 : -1;
|
|
418
|
+
if(isNaB(b_)) return 1;
|
|
419
|
+
return a_ < b_ ? -1 : 1;
|
|
420
|
+
} else if (typeof a_ === 'string' || typeof b_ === 'string') {
|
|
421
|
+
if(typeof b_ !== 'string') return -1;
|
|
422
|
+
if(typeof a_ !== 'string') return 1;
|
|
423
|
+
return a_.localeCompare(b_, 'en');
|
|
424
|
+
} else if(Array.isArray(a_) || Array.isArray(b_)) {
|
|
425
|
+
if(!Array.isArray(a_) || !Array.isArray(b_)) return a_ < b_ ? -1 : 1;
|
|
426
|
+
const length = Math.min(a_.length, b_.length);
|
|
427
|
+
for(let i = 0; i < length; i++) {
|
|
428
|
+
const cmp = internalCompare_(a_[i], b_[i]);
|
|
429
|
+
if(cmp !== 0) return cmp;
|
|
430
|
+
}
|
|
431
|
+
return a_.length - b_.length;
|
|
432
|
+
} else {
|
|
433
|
+
const aKeys = Object.keys(a_).sort();
|
|
434
|
+
const bKeys = Object.keys(b_).sort();
|
|
435
|
+
const keyResult = internalCompare_(aKeys, bKeys);
|
|
436
|
+
if(keyResult !== 0) return keyResult;
|
|
437
|
+
for(const key of aKeys) {
|
|
438
|
+
const result = internalCompare_(a_[key], b_[key]);
|
|
439
|
+
if(result !== 0) return result;
|
|
440
|
+
}
|
|
441
|
+
return 0;
|
|
442
|
+
}
|
|
443
|
+
"""
|
package/lsp/CompletionHandler.ff
CHANGED
|
@@ -15,7 +15,7 @@ data CompletionInfo(
|
|
|
15
15
|
secondarySort: Int = 5
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
handleCompletion(
|
|
18
|
+
handleCompletion(lspHook: LspHook, toplevel: Bool, followedByOpenBracket: Bool): Json {
|
|
19
19
|
let topLevelCompletions = if(!toplevel) {[]} else {toplevelCompletion(lspHook)}
|
|
20
20
|
let patternCompletions = lspHook.results().collectFirst {
|
|
21
21
|
| InferPatternHook h =>
|
|
@@ -156,11 +156,11 @@ handleCompletion(system: NodeSystem, lspHook: LspHook, toplevel: Bool, followedB
|
|
|
156
156
|
} else {c}
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
|
-
completionsToJson(
|
|
159
|
+
completionsToJson([...fixedCompletions, ...fixedTypeCompletions, ...topLevelCompletions])
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
completionsToJson(
|
|
163
|
-
|
|
162
|
+
completionsToJson(completions: List[CompletionInfo]): Json {
|
|
163
|
+
Json.object()
|
|
164
164
|
.with("isIncomplete", False)
|
|
165
165
|
.with("items", completions.distinct().toArray().map {| CompletionInfo i =>
|
|
166
166
|
let shownType = i.type.show([])
|
|
@@ -179,7 +179,7 @@ completionsToJson(js: JsSystem, completions: List[CompletionInfo]): JsValue {
|
|
|
179
179
|
| Pair(TConstructor(_, n1, _), Some(TConstructor(_, n2, _))) => n1 == n2
|
|
180
180
|
| _ => False
|
|
181
181
|
}
|
|
182
|
-
|
|
182
|
+
Json.object()
|
|
183
183
|
// Namespace or Property or Constructor or EnumMember or Constructor or Method/Function or Field/Variable
|
|
184
184
|
.with("kind"
|
|
185
185
|
if(shownType == "") {3} else:
|
|
@@ -192,12 +192,12 @@ completionsToJson(js: JsSystem, completions: List[CompletionInfo]): JsValue {
|
|
|
192
192
|
.with("sortText", sortText)
|
|
193
193
|
.with("preselect", preselect)
|
|
194
194
|
.with("label", i.label)
|
|
195
|
-
.with("labelDetails",
|
|
195
|
+
.with("labelDetails", Json.object()
|
|
196
196
|
.with("detail", i.extra + if(shownType == "") {""} else {": " + shownType})
|
|
197
197
|
)
|
|
198
198
|
.with("insertText", i.snippet)
|
|
199
199
|
.with("insertTextFormat", 2 /* Snippet */)
|
|
200
|
-
.with("documentation",
|
|
200
|
+
.with("documentation", Json.object()
|
|
201
201
|
.with("kind", "markdown")
|
|
202
202
|
.with("value", "```\n" + i.documentation + "\n```")
|
|
203
203
|
)
|
package/lsp/Handler.ff
CHANGED
|
@@ -291,8 +291,8 @@ extend self: Handler {
|
|
|
291
291
|
} catch {| CompileError(at, message), error =>
|
|
292
292
|
Log.trace("handleCompletion check error: " + message)
|
|
293
293
|
} grab()
|
|
294
|
-
let o = CompletionHandler.handleCompletion(
|
|
295
|
-
Result(o.
|
|
294
|
+
let o = CompletionHandler.handleCompletion(lspHook, completionAt.column == 1, token.followedByLeftBracket)
|
|
295
|
+
Result(o.write())
|
|
296
296
|
}
|
|
297
297
|
|
|
298
298
|
handleSignatureHelp(system: NodeSystem, parameters: Map[String, Json]): ResultOrError {
|
package/lsp/LanguageServer.ff
CHANGED
|
@@ -6,12 +6,12 @@ class LanguageServer(
|
|
|
6
6
|
|
|
7
7
|
data BadRequestException(reason: String)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
data Request(
|
|
10
10
|
headers: Map[String, String]
|
|
11
11
|
object: Json
|
|
12
12
|
)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
data RequestMessage(
|
|
15
15
|
id: Option[MessageId] // None when the request is a Notification Message
|
|
16
16
|
method: String
|
|
17
17
|
parameters: Map[String, Json]
|
package/lsp/SymbolHandler.ff
CHANGED
|
@@ -62,7 +62,7 @@ handleWorkspaceSymbol(system: NodeSystem, resultHooks: List[ResultHook], query:
|
|
|
62
62
|
//Log.trace("handleWorkspaceSymbol")
|
|
63
63
|
//workspaceSymbols.each {Log.show(_)}
|
|
64
64
|
let jsSymbols = foundSymbols.map {workspaceSymbolToLsp(system.path("."), _)}
|
|
65
|
-
//workspaceSymbolsJs.each {Log.trace(_.
|
|
65
|
+
//workspaceSymbolsJs.each {Log.trace(_.write(None))}
|
|
66
66
|
jsSymbols
|
|
67
67
|
}
|
|
68
68
|
|
package/lux/Main.ff
CHANGED
|
@@ -71,8 +71,8 @@ nodeMain(system: NodeSystem) {
|
|
|
71
71
|
system.mainTask().sleep(Duration(question.size().toFloat()))
|
|
72
72
|
response.writeText("Hi! You need to give an OpenAI secret key at the command line.")
|
|
73
73
|
| Some(key) =>
|
|
74
|
-
let chatJson = encodeChat(
|
|
75
|
-
let answer = fetchAnswer(system.httpClient(),
|
|
74
|
+
let chatJson = encodeChat(question)
|
|
75
|
+
let answer = fetchAnswer(system.httpClient(), key, chatJson)
|
|
76
76
|
response.writeText(answer)
|
|
77
77
|
}
|
|
78
78
|
} else {
|
|
@@ -81,7 +81,7 @@ nodeMain(system: NodeSystem) {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
fetchAnswer(httpClient: HttpClient,
|
|
84
|
+
fetchAnswer(httpClient: HttpClient, key: String, question: Json): String {
|
|
85
85
|
let json = httpClient.fetch(
|
|
86
86
|
url = "https://api.openai.com/v1/chat/completions"
|
|
87
87
|
method = "POST"
|
|
@@ -89,22 +89,21 @@ fetchAnswer(httpClient: HttpClient, js: JsSystem, key: String, question: JsValue
|
|
|
89
89
|
Pair("Authorization", "Bearer " + key)
|
|
90
90
|
Pair("Content-Type", "application/json")
|
|
91
91
|
]
|
|
92
|
-
body = Some(HttpClient.bodyText(question.
|
|
93
|
-
).
|
|
94
|
-
|
|
92
|
+
body = Some(HttpClient.bodyText(question.write()))
|
|
93
|
+
).readJson()
|
|
94
|
+
json.field("choices").index(0).field("message").field("content").grabString()
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
encodeChat(
|
|
98
|
-
let systemJson =
|
|
97
|
+
encodeChat(question: String): Json {
|
|
98
|
+
let systemJson = Json.object()
|
|
99
99
|
.with("role", "system")
|
|
100
100
|
.with("content", "You are a helpful assistant.")
|
|
101
|
-
let questionJson =
|
|
101
|
+
let questionJson = Json.object()
|
|
102
102
|
.with("role", "user")
|
|
103
103
|
.with("content", question)
|
|
104
|
-
|
|
105
|
-
js.object()
|
|
104
|
+
Json.object()
|
|
106
105
|
.with("model", "gpt-3.5-turbo")
|
|
107
|
-
.with("messages",
|
|
106
|
+
.with("messages", [systemJson, questionJson])
|
|
108
107
|
}
|
|
109
108
|
|
|
110
109
|
|
|
@@ -182,6 +182,10 @@ export function FetchResponse_readText(self_) {
|
|
|
182
182
|
throw new Error('Function FetchResponse_readText is missing on this target in sync context.');
|
|
183
183
|
}
|
|
184
184
|
|
|
185
|
+
export function FetchResponse_readJson(self_) {
|
|
186
|
+
throw new Error('Function FetchResponse_readJson is missing on this target in sync context.');
|
|
187
|
+
}
|
|
188
|
+
|
|
185
189
|
export function FetchResponse_readBuffer(self_) {
|
|
186
190
|
throw new Error('Function FetchResponse_readBuffer is missing on this target in sync context.');
|
|
187
191
|
}
|
|
@@ -211,6 +215,10 @@ export async function FetchResponse_readText$(self_, $task) {
|
|
|
211
215
|
return await self_.text()
|
|
212
216
|
}
|
|
213
217
|
|
|
218
|
+
export async function FetchResponse_readJson$(self_, $task) {
|
|
219
|
+
return await self_.json()
|
|
220
|
+
}
|
|
221
|
+
|
|
214
222
|
export async function FetchResponse_readBuffer$(self_, $task) {
|
|
215
223
|
return new DataView(await self_.arrayBuffer())
|
|
216
224
|
}
|
|
@@ -371,10 +371,6 @@ export function JsValue_new9(self_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_,
|
|
|
371
371
|
return new self_(a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8_, a9_)
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
-
export function JsValue_toJson(self_, space_ = ff_core_Option.None()) {
|
|
375
|
-
return JSON.stringify(self_, null, space_.value_)
|
|
376
|
-
}
|
|
377
|
-
|
|
378
374
|
export function JsValue_grabPairs(self_) {
|
|
379
375
|
|
|
380
376
|
if(!(self_ instanceof Object)) throw new Error('Expected object, got '+ typeof self_);;
|
|
@@ -665,10 +661,6 @@ export async function JsValue_new9$(self_, a1_, a2_, a3_, a4_, a5_, a6_, a7_, a8
|
|
|
665
661
|
throw new Error('Function JsValue_new9 is missing on this target in async context.');
|
|
666
662
|
}
|
|
667
663
|
|
|
668
|
-
export async function JsValue_toJson$(self_, space_ = ff_core_Option.None(), $task) {
|
|
669
|
-
throw new Error('Function JsValue_toJson is missing on this target in async context.');
|
|
670
|
-
}
|
|
671
|
-
|
|
672
664
|
export async function JsValue_grabPairs$(self_, $task) {
|
|
673
665
|
throw new Error('Function JsValue_grabPairs is missing on this target in async context.');
|
|
674
666
|
}
|
|
@@ -163,7 +163,7 @@ export function fields_(body_) {
|
|
|
163
163
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
|
-
export function internalWith_(field_, json_) {
|
|
166
|
+
export function internalWith_(self_, field_, json_) {
|
|
167
167
|
|
|
168
168
|
if(typeof self_ !== 'object' || self_ === null || Array.isArray(self_)) {
|
|
169
169
|
throw new Error('Not an object: ' + JSON.stringify(self_));
|
|
@@ -180,6 +180,73 @@ export function internalEachWhile_(self_, body_) {
|
|
|
180
180
|
for(const [key, value] of Object.entries(self_)) if(!body_(key, value)) break
|
|
181
181
|
}
|
|
182
182
|
|
|
183
|
+
export function internalEquals_(a_, b_) {
|
|
184
|
+
|
|
185
|
+
if(a_ === b_) {
|
|
186
|
+
return true;
|
|
187
|
+
} else if(Array.isArray(a_) || Array.isArray(b_)) {
|
|
188
|
+
if(!Array.isArray(a_) || !Array.isArray(b_)) return false;
|
|
189
|
+
if(a_.length !== b_.length) return false;
|
|
190
|
+
for(let i = 0; i < a_.length; i++) {
|
|
191
|
+
if(!internalEquals_(a_[i], b_[i])) return false;
|
|
192
|
+
}
|
|
193
|
+
return true;
|
|
194
|
+
} else if(typeof a_ === 'object' && typeof b_ === 'object' && a_ !== null && b_ !== null) {
|
|
195
|
+
const aKeys = Object.keys(a_);
|
|
196
|
+
const bKeys = Object.keys(b_);
|
|
197
|
+
if(aKeys.length !== bKeys.length) return false;
|
|
198
|
+
for(const key of aKeys) {
|
|
199
|
+
if(!Object.hasOwn(b_, key) || !internalEquals_(a_[key], b_[key])) return false;
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
} else {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
export function internalCompare_(a_, b_) {
|
|
209
|
+
|
|
210
|
+
if(a_ === b_) {
|
|
211
|
+
return 0;
|
|
212
|
+
} else if (a_ === null || b_ === null) {
|
|
213
|
+
return a_ === null ? -1 : 1;
|
|
214
|
+
} else if (typeof a_ === 'boolean' || typeof b_ === 'boolean') {
|
|
215
|
+
if(typeof b_ !== 'boolean') return -1;
|
|
216
|
+
if(typeof a_ !== 'boolean') return 1;
|
|
217
|
+
return a_ < b_ ? -1 : 1;
|
|
218
|
+
} else if (typeof a_ === 'number' || typeof b_ === 'number') {
|
|
219
|
+
if(typeof b_ !== 'number') return -1;
|
|
220
|
+
if(typeof a_ !== 'number') return 1;
|
|
221
|
+
if(isNaB(a_)) return isNaB(b_) ? 0 : -1;
|
|
222
|
+
if(isNaB(b_)) return 1;
|
|
223
|
+
return a_ < b_ ? -1 : 1;
|
|
224
|
+
} else if (typeof a_ === 'string' || typeof b_ === 'string') {
|
|
225
|
+
if(typeof b_ !== 'string') return -1;
|
|
226
|
+
if(typeof a_ !== 'string') return 1;
|
|
227
|
+
return a_.localeCompare(b_, 'en');
|
|
228
|
+
} else if(Array.isArray(a_) || Array.isArray(b_)) {
|
|
229
|
+
if(!Array.isArray(a_) || !Array.isArray(b_)) return a_ < b_ ? -1 : 1;
|
|
230
|
+
const length = Math.min(a_.length, b_.length);
|
|
231
|
+
for(let i = 0; i < length; i++) {
|
|
232
|
+
const cmp = internalCompare_(a_[i], b_[i]);
|
|
233
|
+
if(cmp !== 0) return cmp;
|
|
234
|
+
}
|
|
235
|
+
return a_.length - b_.length;
|
|
236
|
+
} else {
|
|
237
|
+
const aKeys = Object.keys(a_).sort();
|
|
238
|
+
const bKeys = Object.keys(b_).sort();
|
|
239
|
+
const keyResult = internalCompare_(aKeys, bKeys);
|
|
240
|
+
if(keyResult !== 0) return keyResult;
|
|
241
|
+
for(const key of aKeys) {
|
|
242
|
+
const result = internalCompare_(a_[key], b_[key]);
|
|
243
|
+
if(result !== 0) return result;
|
|
244
|
+
}
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
|
|
183
250
|
export async function read_$(json_, $task) {
|
|
184
251
|
throw new Error('Function read is missing on this target in async context.');
|
|
185
252
|
}
|
|
@@ -224,7 +291,7 @@ export async function fields_$(body_, $task) {
|
|
|
224
291
|
|
|
225
292
|
}
|
|
226
293
|
|
|
227
|
-
export async function internalWith_$(field_, json_, $task) {
|
|
294
|
+
export async function internalWith_$(self_, field_, json_, $task) {
|
|
228
295
|
throw new Error('Function internalWith is missing on this target in async context.');
|
|
229
296
|
}
|
|
230
297
|
|
|
@@ -236,14 +303,22 @@ export async function internalEachWhile_$(self_, body_, $task) {
|
|
|
236
303
|
for(const [key, value] of Object.entries(self_)) if(!await body_(key, value, $task)) break
|
|
237
304
|
}
|
|
238
305
|
|
|
239
|
-
export function
|
|
306
|
+
export async function internalEquals_$(a_, b_, $task) {
|
|
307
|
+
throw new Error('Function internalEquals is missing on this target in async context.');
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export async function internalCompare_$(a_, b_, $task) {
|
|
311
|
+
throw new Error('Function internalCompare is missing on this target in async context.');
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function Json_write(self_, indentation_ = ff_core_Option.None()) {
|
|
240
315
|
|
|
241
316
|
return JSON.stringify(self_, null, space_.value_);
|
|
242
317
|
|
|
243
318
|
}
|
|
244
319
|
|
|
245
320
|
export function Json_with(self_, field_, value_, ff_core_Json_JsonLike$T) {
|
|
246
|
-
return ff_core_Json.internalWith_(field_, ff_core_Json_JsonLike$T.toJson_(value_))
|
|
321
|
+
return ff_core_Json.internalWith_(self_, field_, ff_core_Json_JsonLike$T.toJson_(value_))
|
|
247
322
|
}
|
|
248
323
|
|
|
249
324
|
export function Json_merge(self_, that_) {
|
|
@@ -467,12 +542,12 @@ throw Object.assign(new Error(), {ffException: ff_core_Any.toAny_(ff_core_Core.G
|
|
|
467
542
|
ff_core_Json.internalEachWhile_(self_, body_)
|
|
468
543
|
}
|
|
469
544
|
|
|
470
|
-
export async function Json_write$(self_,
|
|
545
|
+
export async function Json_write$(self_, indentation_ = ff_core_Option.None(), $task) {
|
|
471
546
|
throw new Error('Function Json_write is missing on this target in async context.');
|
|
472
547
|
}
|
|
473
548
|
|
|
474
549
|
export async function Json_with$(self_, field_, value_, ff_core_Json_JsonLike$T, $task) {
|
|
475
|
-
return ff_core_Json.internalWith_(field_, ff_core_Json_JsonLike$T.toJson_(value_))
|
|
550
|
+
return ff_core_Json.internalWith_(self_, field_, ff_core_Json_JsonLike$T.toJson_(value_))
|
|
476
551
|
}
|
|
477
552
|
|
|
478
553
|
export async function Json_merge$(self_, that_, $task) {
|
|
@@ -866,4 +941,132 @@ return ff_core_Array.Array_toList(_w1)
|
|
|
866
941
|
}
|
|
867
942
|
}}
|
|
868
943
|
|
|
944
|
+
export function ff_core_Json_JsonLike$ff_core_StringMap_StringMap(ff_core_Json_JsonLike$T) { return {
|
|
945
|
+
toJson_(value_) {
|
|
946
|
+
return ff_core_Json.fields_(((setField_) => {
|
|
947
|
+
ff_core_StringMap.StringMap_each(value_, ((key_, value_) => {
|
|
948
|
+
setField_(key_, ff_core_Json_JsonLike$T.toJson_(value_))
|
|
949
|
+
}))
|
|
950
|
+
}))
|
|
951
|
+
},
|
|
952
|
+
fromJson_(json_) {
|
|
953
|
+
return ff_core_Option.Option_flatten((ff_core_Json.Json_isObject(json_)
|
|
954
|
+
? ff_core_Option.Some((function() {
|
|
955
|
+
const map_ = ff_core_StringMap.make_();
|
|
956
|
+
let convertible_ = true;
|
|
957
|
+
ff_core_Json.Json_eachWhile(json_, ((key_, value_) => {
|
|
958
|
+
do {
|
|
959
|
+
const _1 = ff_core_Json_JsonLike$T.fromJson_(value_);
|
|
960
|
+
{
|
|
961
|
+
if(_1.None) {
|
|
962
|
+
convertible_ = false
|
|
963
|
+
break
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
{
|
|
967
|
+
if(_1.Some) {
|
|
968
|
+
const v_ = _1.value_;
|
|
969
|
+
ff_core_StringMap.StringMap_set(map_, key_, v_)
|
|
970
|
+
break
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
} while(false);
|
|
974
|
+
return convertible_
|
|
975
|
+
}));
|
|
976
|
+
if(convertible_) {
|
|
977
|
+
return ff_core_Option.Some(map_)
|
|
978
|
+
} else return ff_core_Option.None()
|
|
979
|
+
})())
|
|
980
|
+
: ff_core_Option.None()))
|
|
981
|
+
},
|
|
982
|
+
async toJson_$(value_, $task) {
|
|
983
|
+
return ff_core_Json.fields_(((setField_) => {
|
|
984
|
+
ff_core_StringMap.StringMap_each(value_, ((key_, value_) => {
|
|
985
|
+
setField_(key_, ff_core_Json_JsonLike$T.toJson_(value_))
|
|
986
|
+
}))
|
|
987
|
+
}))
|
|
988
|
+
},
|
|
989
|
+
async fromJson_$(json_, $task) {
|
|
990
|
+
return ff_core_Option.Option_flatten((ff_core_Json.Json_isObject(json_)
|
|
991
|
+
? ff_core_Option.Some((await (async function() {
|
|
992
|
+
const map_ = ff_core_StringMap.make_();
|
|
993
|
+
let convertible_ = true;
|
|
994
|
+
ff_core_Json.Json_eachWhile(json_, ((key_, value_) => {
|
|
995
|
+
do {
|
|
996
|
+
const _1 = ff_core_Json_JsonLike$T.fromJson_(value_);
|
|
997
|
+
{
|
|
998
|
+
if(_1.None) {
|
|
999
|
+
convertible_ = false
|
|
1000
|
+
break
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
{
|
|
1004
|
+
if(_1.Some) {
|
|
1005
|
+
const v_ = _1.value_;
|
|
1006
|
+
ff_core_StringMap.StringMap_set(map_, key_, v_)
|
|
1007
|
+
break
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
} while(false);
|
|
1011
|
+
return convertible_
|
|
1012
|
+
}));
|
|
1013
|
+
if(convertible_) {
|
|
1014
|
+
return ff_core_Option.Some(map_)
|
|
1015
|
+
} else return ff_core_Option.None()
|
|
1016
|
+
})()))
|
|
1017
|
+
: ff_core_Option.None()))
|
|
1018
|
+
}
|
|
1019
|
+
}}
|
|
1020
|
+
|
|
1021
|
+
export const ff_core_Any_HasAnyTag$ff_core_Json_Json = {
|
|
1022
|
+
anyTag_() {
|
|
1023
|
+
return ff_core_Any.internalAnyTag_("ff:core/Json.Json[]")
|
|
1024
|
+
},
|
|
1025
|
+
async anyTag_$($task) {
|
|
1026
|
+
return ff_core_Any.internalAnyTag_("ff:core/Json.Json[]")
|
|
1027
|
+
}
|
|
1028
|
+
};
|
|
1029
|
+
|
|
1030
|
+
export const ff_core_Show_Show$ff_core_Json_Json = {
|
|
1031
|
+
show_(value_) {
|
|
1032
|
+
return ff_core_Json.Json_write(value_, ff_core_Option.Some(" "))
|
|
1033
|
+
},
|
|
1034
|
+
async show_$(value_, $task) {
|
|
1035
|
+
return ff_core_Json.Json_write(value_, ff_core_Option.Some(" "))
|
|
1036
|
+
}
|
|
1037
|
+
};
|
|
1038
|
+
|
|
1039
|
+
export const ff_core_Equal_Equal$ff_core_Json_Json = {
|
|
1040
|
+
equals_(a_, b_) {
|
|
1041
|
+
return ff_core_Json.internalEquals_(a_, b_)
|
|
1042
|
+
},
|
|
1043
|
+
async equals_$(a_, b_, $task) {
|
|
1044
|
+
return ff_core_Json.internalEquals_(a_, b_)
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
|
|
1048
|
+
export const ff_core_Ordering_Order$ff_core_Json_Json = {
|
|
1049
|
+
compare_(a_, b_) {
|
|
1050
|
+
return ff_core_Ordering.fromInt_(ff_core_Json.internalCompare_(a_, b_))
|
|
1051
|
+
},
|
|
1052
|
+
async compare_$(a_, b_, $task) {
|
|
1053
|
+
return ff_core_Ordering.fromInt_(ff_core_Json.internalCompare_(a_, b_))
|
|
1054
|
+
}
|
|
1055
|
+
};
|
|
1056
|
+
|
|
1057
|
+
export const ff_core_Serializable_Serializable$ff_core_Json_Json = {
|
|
1058
|
+
serializeUsing_(serialization_, value_) {
|
|
1059
|
+
ff_core_Serializable.ff_core_Serializable_Serializable$ff_core_String_String.serializeUsing_(serialization_, ff_core_Json.Json_write(value_, ff_core_Option.None()))
|
|
1060
|
+
},
|
|
1061
|
+
deserializeUsing_(serialization_) {
|
|
1062
|
+
return ff_core_Option.Option_grab(ff_core_Json.read_(ff_core_Serializable.ff_core_Serializable_Serializable$ff_core_String_String.deserializeUsing_(serialization_)))
|
|
1063
|
+
},
|
|
1064
|
+
async serializeUsing_$(serialization_, value_, $task) {
|
|
1065
|
+
ff_core_Serializable.ff_core_Serializable_Serializable$ff_core_String_String.serializeUsing_(serialization_, ff_core_Json.Json_write(value_, ff_core_Option.None()))
|
|
1066
|
+
},
|
|
1067
|
+
async deserializeUsing_$(serialization_, $task) {
|
|
1068
|
+
return ff_core_Option.Option_grab(ff_core_Json.read_(ff_core_Serializable.ff_core_Serializable_Serializable$ff_core_String_String.deserializeUsing_(serialization_)))
|
|
1069
|
+
}
|
|
1070
|
+
};
|
|
1071
|
+
|
|
869
1072
|
|
package/package.json
CHANGED