firefly-compiler 0.4.79 → 0.4.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/.hintrc +4 -4
  2. package/.vscode/settings.json +4 -4
  3. package/bin/Release.ff +153 -153
  4. package/bin/firefly.mjs +1 -1
  5. package/compiler/Builder.ff +257 -257
  6. package/compiler/Compiler.ff +227 -227
  7. package/compiler/Dependencies.ff +187 -187
  8. package/compiler/DependencyLock.ff +17 -17
  9. package/compiler/Inference.ff +2 -1
  10. package/compiler/JsEmitter.ff +940 -946
  11. package/compiler/LspHook.ff +202 -202
  12. package/compiler/Main.ff +3 -3
  13. package/compiler/ModuleCache.ff +178 -178
  14. package/compiler/Tokenizer.ff +1 -1
  15. package/compiler/Unification.ff +1 -1
  16. package/compiler/Workspace.ff +88 -88
  17. package/core/.firefly/include/package-lock.json +564 -564
  18. package/core/.firefly/include/package.json +5 -5
  19. package/core/.firefly/include/prepare.sh +1 -1
  20. package/core/.firefly/package.ff +2 -2
  21. package/core/Array.ff +265 -265
  22. package/core/Atomic.ff +64 -64
  23. package/core/Box.ff +7 -7
  24. package/core/BrowserSystem.ff +40 -40
  25. package/core/BuildSystem.ff +148 -148
  26. package/core/Crypto.ff +96 -96
  27. package/core/Equal.ff +36 -36
  28. package/core/Float.ff +25 -0
  29. package/core/HttpClient.ff +148 -148
  30. package/core/JsSystem.ff +69 -69
  31. package/core/Json.ff +434 -434
  32. package/core/List.ff +486 -486
  33. package/core/Lock.ff +144 -144
  34. package/core/NodeSystem.ff +216 -216
  35. package/core/Ordering.ff +161 -161
  36. package/core/Path.ff +401 -401
  37. package/core/Random.ff +134 -134
  38. package/core/RbMap.ff +216 -216
  39. package/core/Show.ff +43 -43
  40. package/core/SourceLocation.ff +68 -68
  41. package/core/Stream.ff +9 -9
  42. package/core/Task.ff +149 -141
  43. package/core/Try.ff +25 -4
  44. package/experimental/benchmarks/ListGrab.ff +23 -23
  45. package/experimental/benchmarks/ListGrab.java +55 -55
  46. package/experimental/benchmarks/Pyrotek45.ff +30 -30
  47. package/experimental/benchmarks/Pyrotek45.java +64 -64
  48. package/experimental/bidirectional/Bidi.ff +88 -88
  49. package/experimental/random/Index.ff +53 -53
  50. package/experimental/random/Process.ff +120 -120
  51. package/experimental/random/Scrape.ff +51 -51
  52. package/experimental/random/Symbols.ff +73 -73
  53. package/experimental/random/Tensor.ff +52 -52
  54. package/experimental/random/Units.ff +36 -36
  55. package/experimental/s3/S3TestAuthorizationHeader.ff +39 -39
  56. package/experimental/s3/S3TestPut.ff +16 -16
  57. package/experimental/tests/TestJson.ff +26 -26
  58. package/firefly.sh +0 -0
  59. package/fireflysite/.firefly/package.ff +4 -4
  60. package/fireflysite/CommunityOverview.ff +20 -20
  61. package/fireflysite/CountingButtonDemo.ff +58 -58
  62. package/fireflysite/DocumentParser.ff +331 -217
  63. package/fireflysite/ExamplesOverview.ff +40 -40
  64. package/fireflysite/FrontPage.ff +344 -360
  65. package/fireflysite/{GuideIntroduction.ff → GettingStarted.ff} +45 -52
  66. package/fireflysite/Guide.ff +442 -411
  67. package/fireflysite/Main.ff +151 -137
  68. package/fireflysite/MatchingPasswordsDemo.ff +82 -82
  69. package/fireflysite/PackagesOverview.ff +49 -49
  70. package/fireflysite/PostgresqlDemo.ff +34 -34
  71. package/fireflysite/ReferenceAll.ff +18 -0
  72. package/fireflysite/ReferenceIntroduction.ff +11 -0
  73. package/fireflysite/Styles.ff +567 -495
  74. package/fireflysite/Test.ff +46 -0
  75. package/fireflysite/assets/markdown/reference/BaseTypes.md +209 -0
  76. package/fireflysite/assets/markdown/reference/EmittedJavascript.md +66 -0
  77. package/fireflysite/assets/markdown/reference/Exceptions.md +101 -0
  78. package/fireflysite/assets/markdown/reference/FunctionsAndMethods.md +338 -0
  79. package/fireflysite/assets/markdown/reference/JavascriptInterop.md +134 -0
  80. package/fireflysite/assets/markdown/reference/ModulesAndPackages.md +162 -0
  81. package/fireflysite/assets/markdown/reference/OldStructuredConcurrency.md +48 -0
  82. package/fireflysite/assets/markdown/reference/PatternMatching.md +224 -0
  83. package/fireflysite/assets/markdown/reference/StatementsAndExpressions.md +86 -0
  84. package/fireflysite/assets/markdown/reference/StructuredConcurrency.md +99 -0
  85. package/fireflysite/assets/markdown/reference/TraitsAndInstances.md +100 -0
  86. package/fireflysite/assets/markdown/reference/UserDefinedTypes.md +184 -0
  87. package/fireflysite/assets/markdown/{ControlFlow.md → scratch/ControlFlow.md} +136 -136
  88. package/fireflysite/assets/markdown/scratch/Toc.md +41 -0
  89. package/lsp/.firefly/package.ff +1 -1
  90. package/lsp/CompletionHandler.ff +828 -828
  91. package/lsp/Handler.ff +714 -714
  92. package/lsp/HoverHandler.ff +79 -79
  93. package/lsp/LanguageServer.ff +272 -272
  94. package/lsp/SignatureHelpHandler.ff +55 -55
  95. package/lsp/SymbolHandler.ff +181 -181
  96. package/lsp/TestReferences.ff +17 -17
  97. package/lsp/TestReferencesCase.ff +7 -7
  98. package/lsp/stderr.txt +1 -1
  99. package/lsp/stdout.txt +34 -34
  100. package/lux/.firefly/package.ff +1 -1
  101. package/lux/Css.ff +648 -648
  102. package/lux/CssTest.ff +48 -48
  103. package/lux/Lux.ff +593 -487
  104. package/lux/LuxEvent.ff +116 -116
  105. package/lux/Main.ff +123 -123
  106. package/lux/Main2.ff +143 -143
  107. package/lux/TestDry.ff +27 -0
  108. package/output/js/ff/compiler/Builder.mjs +47 -47
  109. package/output/js/ff/compiler/Dependencies.mjs +3 -3
  110. package/output/js/ff/compiler/Inference.mjs +2 -2
  111. package/output/js/ff/compiler/JsEmitter.mjs +18 -72
  112. package/output/js/ff/compiler/Main.mjs +4 -4
  113. package/output/js/ff/compiler/ModuleCache.mjs +4 -4
  114. package/output/js/ff/core/Array.mjs +59 -59
  115. package/output/js/ff/core/Atomic.mjs +36 -36
  116. package/output/js/ff/core/BrowserSystem.mjs +11 -11
  117. package/output/js/ff/core/BuildSystem.mjs +30 -30
  118. package/output/js/ff/core/Crypto.mjs +40 -40
  119. package/output/js/ff/core/Float.mjs +50 -0
  120. package/output/js/ff/core/HttpClient.mjs +56 -56
  121. package/output/js/ff/core/Json.mjs +147 -147
  122. package/output/js/ff/core/List.mjs +50 -50
  123. package/output/js/ff/core/Lock.mjs +97 -97
  124. package/output/js/ff/core/NodeSystem.mjs +87 -87
  125. package/output/js/ff/core/Ordering.mjs +8 -8
  126. package/output/js/ff/core/Path.mjs +231 -231
  127. package/output/js/ff/core/Random.mjs +56 -56
  128. package/output/js/ff/core/Task.mjs +71 -39
  129. package/output/js/ff/core/Try.mjs +98 -4
  130. package/package.json +1 -1
  131. package/postgresql/Pg.ff +1 -1
  132. package/rpc/.firefly/package.ff +1 -1
  133. package/rpc/Rpc.ff +70 -70
  134. package/s3/.firefly/package.ff +1 -1
  135. package/s3/S3.ff +94 -94
  136. package/unsafejs/UnsafeJs.ff +19 -19
  137. package/vscode/LICENSE.txt +21 -21
  138. package/vscode/Prepublish.ff +15 -15
  139. package/vscode/README.md +16 -16
  140. package/vscode/client/package.json +22 -22
  141. package/vscode/client/src/extension.ts +104 -104
  142. package/vscode/icons/firefly-icon.svg +10 -10
  143. package/vscode/language-configuration.json +61 -61
  144. package/vscode/package-lock.json +3623 -3623
  145. package/vscode/package.json +1 -1
  146. package/vscode/snippets.json +241 -241
  147. package/vscode/syntaxes/firefly-markdown-injection.json +45 -45
  148. package/webserver/.firefly/include/package-lock.json +22 -22
  149. package/webserver/.firefly/include/package.json +5 -5
  150. package/webserver/.firefly/package.ff +2 -2
  151. package/webserver/WebServer.ff +685 -685
  152. package/websocket/.firefly/package.ff +1 -1
  153. package/websocket/WebSocket.ff +131 -131
  154. package/fireflysite/GuideAll.ff +0 -21
  155. package/fireflysite/GuideBaseTypes.ff +0 -168
  156. package/fireflysite/GuideControlFlow.ff +0 -212
  157. package/fireflysite/assets/markdown/Example.md +0 -78
  158. /package/fireflysite/assets/{NotoSansMono-Regular.ttf → font/NotoSansMono-Regular.ttf} +0 -0
  159. /package/fireflysite/assets/{NunitoSans-VariableFont_YTLC,opsz,wdth,wght.ttf → font/NunitoSans-VariableFont_YTLC,opsz,wdth,wght.ttf} +0 -0
  160. /package/fireflysite/assets/{autocomplete-small.png → image/autocomplete-small.png} +0 -0
  161. /package/fireflysite/assets/{autocomplete.png → image/autocomplete.png} +0 -0
  162. /package/fireflysite/assets/{edit-time-error.png → image/edit-time-error.png} +0 -0
  163. /package/fireflysite/assets/{firefly-logo-notext.png → image/firefly-logo-notext.png} +0 -0
  164. /package/fireflysite/assets/{firefly-logo-yellow.png → image/firefly-logo-yellow.png} +0 -0
package/core/Box.ff CHANGED
@@ -1,7 +1,7 @@
1
- class Box[T](mutable value: T)
2
-
3
- extend self[T]: Box[T] {
4
- modify(body: T => T): Unit {
5
- self.value = body(self.value)
6
- }
7
- }
1
+ class Box[T](mutable value: T)
2
+
3
+ extend self[T]: Box[T] {
4
+ modify(body: T => T): Unit {
5
+ self.value = body(self.value)
6
+ }
7
+ }
@@ -1,40 +1,40 @@
1
- capability BrowserSystem {}
2
-
3
- extend self: BrowserSystem {
4
-
5
- httpClient(): HttpClient
6
- target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
7
-
8
- mainTask(): Task
9
- target js async "return self_.task_"
10
-
11
- crypto(): Crypto
12
- target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
13
-
14
- js(): JsSystem
15
- target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
16
-
17
- url(): String
18
- target js async """
19
- return location.href;
20
- """
21
-
22
- urlPath(): String
23
- target js async """
24
- return location.pathname;
25
- """
26
-
27
- urlQuery(name: String): Option[String]
28
- target js async """
29
- const param = new URLSearchParams(location.search).get(name_)
30
- if(param == null) return ff_core_Option.None();
31
- return ff_core_Option.Some(param);
32
- """
33
-
34
- urlFragment(): Option[String]
35
- target js async """
36
- if(!location.hash.startsWith('#')) return ff_core_Option.None();
37
- return ff_core_Option.Some(location.hash.slice(1));
38
- """
39
-
40
- }
1
+ capability BrowserSystem {}
2
+
3
+ extend self: BrowserSystem {
4
+
5
+ httpClient(): HttpClient
6
+ target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
7
+
8
+ mainTask(): Task
9
+ target js async "return self_.task_"
10
+
11
+ crypto(): Crypto
12
+ target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
13
+
14
+ js(): JsSystem
15
+ target js async "return typeof globalThis !== 'undefined' ? globalThis : window"
16
+
17
+ url(): String
18
+ target js async """
19
+ return location.href;
20
+ """
21
+
22
+ urlPath(): String
23
+ target js async """
24
+ return location.pathname;
25
+ """
26
+
27
+ urlQuery(name: String): Option[String]
28
+ target js async """
29
+ const param = new URLSearchParams(location.search).get(name_)
30
+ if(param == null) return ff_core_Option.None();
31
+ return ff_core_Option.Some(param);
32
+ """
33
+
34
+ urlFragment(): Option[String]
35
+ target js async """
36
+ if(!location.hash.startsWith('#')) return ff_core_Option.None();
37
+ return ff_core_Option.Some(location.hash.slice(1));
38
+ """
39
+
40
+ }
@@ -1,148 +1,148 @@
1
- capability BuildSystem {}
2
- capability BrowserCode(packageGroup: String, packageName: String, mainFile: Path, assetSystem: AssetSystem)
3
- capability BrowserBundle(assetSystem: AssetSystem)
4
-
5
- extend self: BuildSystem {
6
-
7
- compileForBrowser(mainFile: String): BrowserCode {
8
- // TODO: Check that the mainFile is in the current package directory
9
- internalCompile(self, internalPath(self, mainFile), "browser")
10
- let streams = internalListDirectory(internalPath(self, ".firefly/output/browser"))
11
- let mainPackagePair = internalMainPackagePair(self)
12
- BrowserCode(
13
- packageGroup = mainPackagePair.first
14
- packageName = mainPackagePair.second
15
- mainFile = internalPath(self, mainFile)
16
- assetSystem = AssetSystem(streams.toMap())
17
- )
18
- }
19
-
20
- buildMode(): Bool
21
- target node async "return !!self_.buildMode_"
22
-
23
- setAssets(assetSystem: AssetSystem): Unit
24
- target node async "self_.assets_ = assetSystem_"
25
-
26
- packageAssets(): AssetSystem {
27
- let streams = internalListDirectory(internalPath(self, "."))
28
- AssetSystem(streams.toMap())
29
- }
30
-
31
- dependencyAssets(user: String, package: String): AssetSystem {
32
- panic("dependencyAssets not yet implemented")
33
- }
34
-
35
- arguments(): List[String]
36
- target node async "return self_.array_"
37
-
38
- mainTask(): Task
39
- target js async "return self_.task_"
40
-
41
- crypto(): Crypto
42
- target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
43
-
44
- }
45
-
46
- extend self: BrowserCode {
47
-
48
- assets(): AssetSystem {
49
- self.assetSystem
50
- }
51
-
52
- bundle(minify: Bool = True, sourceMap: Bool = False): BrowserBundle {
53
- let prefix = ".firefly/output/browser"
54
- let mainJsBaseFile = self.mainFile.base().removeLast(".ff").grab() + ".mjs"
55
- let mainJsFile = prefix + "/" + self.packageGroup + "/" + self.packageName + "/" + mainJsBaseFile
56
- let mainDirectory = self.mainFile.parent().grab()
57
- let file = prefix + "/Main.bundle.js"
58
- internalCallEsBuild(self, mainJsFile = mainJsFile, outputPath = file, minify = minify, sourceMap = sourceMap)
59
- let assets = AssetSystem([
60
- Pair(file.dropFirst(prefix.size()), {mainDirectory.path(file).readStream()})
61
- ...if(sourceMap) {[
62
- Pair(file.dropFirst(prefix.size()) + ".map", {mainDirectory.path(file + ".map").readStream()})
63
- ]} else {[]}
64
- ].toMap())
65
- BrowserBundle(assets)
66
- }
67
-
68
- }
69
-
70
- extend self: BrowserBundle {
71
-
72
- assets(): AssetSystem {
73
- self.assetSystem
74
- }
75
-
76
- }
77
-
78
-
79
- internalCallEsBuild(
80
- self: BrowserCode
81
- mainJsFile: String
82
- outputPath: String
83
- minify: Bool
84
- sourceMap: Bool
85
- ): Unit
86
- target node async """
87
- import * as esbuild from 'esbuild'
88
- return await esbuild.build({
89
- entryPoints: [mainJsFile_],
90
- bundle: true,
91
- minify: minify_,
92
- sourcemap: sourceMap_,
93
- platform: 'browser',
94
- target: 'es6',
95
- external: ['../../../node_modules/*'], // TODO
96
- outfile: outputPath_
97
- })
98
- """
99
-
100
- internalNodeCallEsBuild(
101
- self: NodeSystem
102
- mainJsFile: String
103
- outputPath: String
104
- minify: Bool
105
- ): Unit
106
- target node async """
107
- import * as esbuild from 'esbuild'
108
- return await esbuild.build({
109
- entryPoints: [mainJsFile_],
110
- bundle: true,
111
- minify: minify_,
112
- sourcemap: true,
113
- platform: 'node',
114
- target: 'es6',
115
- external: ['../../../node_modules/*'], // TODO
116
- outfile: outputPath_
117
- })
118
- """
119
-
120
- internalListDirectory(path: Path): List[Pair[String, () => Stream[Buffer]]] {
121
- function go(currentPath: Path): Stream[Path] {
122
- currentPath.entries().flatMap {file =>
123
- if(file.isDirectory()) {
124
- go(file.path())
125
- } else {
126
- [file.path()].toStream()
127
- }
128
- }
129
- }
130
- go(path).map {file =>
131
- Pair("/" + file.relativeTo(path).replace("\\", "/"), {file.readStream()})
132
- }.toList()
133
- }
134
-
135
- internalPath(buildSystem: BuildSystem, absoluteOrRelative: String): Path
136
- target node async """
137
- return absoluteOrRelative_
138
- """
139
-
140
- internalCompile(buildSystem: BuildSystem, mainFile: Path, target: String): Unit
141
- target node async """
142
- return await $firefly_compiler.buildViaBuildSystem_$(buildSystem_, buildSystem_.fireflyPath_, mainFile_, target_, $task)
143
- """
144
-
145
- internalMainPackagePair(buildSystem: BuildSystem): Pair[String, String]
146
- target node async """
147
- return {first_: buildSystem_.mainPackagePair_.group_, second_: buildSystem_.mainPackagePair_.name_}
148
- """
1
+ capability BuildSystem {}
2
+ capability BrowserCode(packageGroup: String, packageName: String, mainFile: Path, assetSystem: AssetSystem)
3
+ capability BrowserBundle(assetSystem: AssetSystem)
4
+
5
+ extend self: BuildSystem {
6
+
7
+ compileForBrowser(mainFile: String): BrowserCode {
8
+ // TODO: Check that the mainFile is in the current package directory
9
+ internalCompile(self, internalPath(self, mainFile), "browser")
10
+ let streams = internalListDirectory(internalPath(self, ".firefly/output/browser"))
11
+ let mainPackagePair = internalMainPackagePair(self)
12
+ BrowserCode(
13
+ packageGroup = mainPackagePair.first
14
+ packageName = mainPackagePair.second
15
+ mainFile = internalPath(self, mainFile)
16
+ assetSystem = AssetSystem(streams.toMap())
17
+ )
18
+ }
19
+
20
+ buildMode(): Bool
21
+ target node async "return !!self_.buildMode_"
22
+
23
+ setAssets(assetSystem: AssetSystem): Unit
24
+ target node async "self_.assets_ = assetSystem_"
25
+
26
+ packageAssets(): AssetSystem {
27
+ let streams = internalListDirectory(internalPath(self, "."))
28
+ AssetSystem(streams.toMap())
29
+ }
30
+
31
+ dependencyAssets(user: String, package: String): AssetSystem {
32
+ panic("dependencyAssets not yet implemented")
33
+ }
34
+
35
+ arguments(): List[String]
36
+ target node async "return self_.array_"
37
+
38
+ mainTask(): Task
39
+ target js async "return self_.task_"
40
+
41
+ crypto(): Crypto
42
+ target js async "return (typeof globalThis !== 'undefined' ? globalThis : window).crypto"
43
+
44
+ }
45
+
46
+ extend self: BrowserCode {
47
+
48
+ assets(): AssetSystem {
49
+ self.assetSystem
50
+ }
51
+
52
+ bundle(minify: Bool = True, sourceMap: Bool = False): BrowserBundle {
53
+ let prefix = ".firefly/output/browser"
54
+ let mainJsBaseFile = self.mainFile.base().removeLast(".ff").grab() + ".mjs"
55
+ let mainJsFile = prefix + "/" + self.packageGroup + "/" + self.packageName + "/" + mainJsBaseFile
56
+ let mainDirectory = self.mainFile.parent().grab()
57
+ let file = prefix + "/Main.bundle.js"
58
+ internalCallEsBuild(self, mainJsFile = mainJsFile, outputPath = file, minify = minify, sourceMap = sourceMap)
59
+ let assets = AssetSystem([
60
+ Pair(file.dropFirst(prefix.size()), {mainDirectory.path(file).readStream()})
61
+ ...if(sourceMap) {[
62
+ Pair(file.dropFirst(prefix.size()) + ".map", {mainDirectory.path(file + ".map").readStream()})
63
+ ]} else {[]}
64
+ ].toMap())
65
+ BrowserBundle(assets)
66
+ }
67
+
68
+ }
69
+
70
+ extend self: BrowserBundle {
71
+
72
+ assets(): AssetSystem {
73
+ self.assetSystem
74
+ }
75
+
76
+ }
77
+
78
+
79
+ internalCallEsBuild(
80
+ self: BrowserCode
81
+ mainJsFile: String
82
+ outputPath: String
83
+ minify: Bool
84
+ sourceMap: Bool
85
+ ): Unit
86
+ target node async """
87
+ import * as esbuild from 'esbuild'
88
+ return await esbuild.build({
89
+ entryPoints: [mainJsFile_],
90
+ bundle: true,
91
+ minify: minify_,
92
+ sourcemap: sourceMap_,
93
+ platform: 'browser',
94
+ target: 'es6',
95
+ external: ['../../../node_modules/*'], // TODO
96
+ outfile: outputPath_
97
+ })
98
+ """
99
+
100
+ internalNodeCallEsBuild(
101
+ self: NodeSystem
102
+ mainJsFile: String
103
+ outputPath: String
104
+ minify: Bool
105
+ ): Unit
106
+ target node async """
107
+ import * as esbuild from 'esbuild'
108
+ return await esbuild.build({
109
+ entryPoints: [mainJsFile_],
110
+ bundle: true,
111
+ minify: minify_,
112
+ sourcemap: true,
113
+ platform: 'node',
114
+ target: 'es6',
115
+ external: ['../../../node_modules/*'], // TODO
116
+ outfile: outputPath_
117
+ })
118
+ """
119
+
120
+ internalListDirectory(path: Path): List[Pair[String, () => Stream[Buffer]]] {
121
+ function go(currentPath: Path): Stream[Path] {
122
+ currentPath.entries().flatMap {file =>
123
+ if(file.isDirectory()) {
124
+ go(file.path())
125
+ } else {
126
+ [file.path()].toStream()
127
+ }
128
+ }
129
+ }
130
+ go(path).map {file =>
131
+ Pair("/" + file.relativeTo(path).replace("\\", "/"), {file.readStream()})
132
+ }.toList()
133
+ }
134
+
135
+ internalPath(buildSystem: BuildSystem, absoluteOrRelative: String): Path
136
+ target node async """
137
+ return absoluteOrRelative_
138
+ """
139
+
140
+ internalCompile(buildSystem: BuildSystem, mainFile: Path, target: String): Unit
141
+ target node async """
142
+ return await $firefly_compiler.buildViaBuildSystem_$(buildSystem_, buildSystem_.fireflyPath_, mainFile_, target_, $task)
143
+ """
144
+
145
+ internalMainPackagePair(buildSystem: BuildSystem): Pair[String, String]
146
+ target node async """
147
+ return {first_: buildSystem_.mainPackagePair_.group_, second_: buildSystem_.mainPackagePair_.name_}
148
+ """
package/core/Crypto.ff CHANGED
@@ -1,96 +1,96 @@
1
- capability Crypto {}
2
-
3
- extend self: Crypto {
4
-
5
- randomUuid(): String
6
- target js async """
7
- return self_.randomUUID();
8
- """
9
-
10
- randomBuffer(size: Int): Buffer {
11
- let buffer = Buffer.new(size)
12
- self.randomizeBuffer(buffer)
13
- buffer
14
- }
15
-
16
- randomizeBuffer(buffer: Buffer): Unit
17
- target js async """
18
- self_.getRandomValues(new Uint8Array(buffer_.buffer, buffer_.byteOffset, buffer_.byteLength));
19
- """
20
-
21
- hmacSha256(key: Buffer, buffer: Buffer): Buffer
22
- target js async """
23
- const cryptoKey = await self_.subtle.importKey(
24
- 'raw',
25
- key_,
26
- {name: 'HMAC', hash: {name: 'SHA-256'}},
27
- false,
28
- ['sign']
29
- );
30
- const signature = await self_.subtle.sign(
31
- 'HMAC',
32
- cryptoKey,
33
- buffer_
34
- );
35
- return new DataView(signature);
36
- """
37
-
38
- sha256(buffer: Buffer): Buffer
39
- target js async """
40
- let hash = await self_.subtle.digest('SHA-256', buffer_);
41
- return new DataView(hash);
42
- """
43
-
44
- hashPassword(password: String, iterations: Int = 600000): String {
45
- let salt = self.randomBuffer(16)
46
- let hash = internalHashPassword(self, salt, password.toBuffer(), iterations)
47
- "$pbkdf2-sha256-hex$" + iterations + "$" + salt.toHex() + "$" + hash.toHex()
48
- }
49
-
50
- checkPassword(password: String, passwordHash: String): Bool {
51
- passwordHash.split('$').{
52
- | ["", "pbkdf2-sha256-hex", iterationsText, saltText, hashText] {
53
- iterationsText.getInt() | Some(iterations)
54
- } =>
55
- let computedHash =
56
- internalHashPassword(self, Buffer.fromHex(saltText), password.toBuffer(), iterations)
57
- let hash = Buffer.fromHex(hashText)
58
- self.constantTimeEquals(computedHash, hash)
59
- | _ => False
60
- }
61
- }
62
-
63
- constantTimeEquals(buffer1: Buffer, buffer2: Buffer): Bool {
64
- if(buffer1.size() != buffer2.size()) {False} else:
65
- mutable v = 0
66
- mutable i = 0
67
- while {i < buffer1.size()} {
68
- v = v.bitOr(buffer1.grabUint8(i).bitXor(buffer2.grabUint8(i)))
69
- i += 1
70
- }
71
- v == 0
72
- }
73
-
74
- }
75
-
76
- internalHashPassword(system: Crypto, salt: Buffer, password: Buffer, iterations: Int): Buffer
77
- target js async """
78
- const keyMaterial = await crypto.subtle.importKey(
79
- 'raw',
80
- password_,
81
- {name: 'PBKDF2'},
82
- false,
83
- ['deriveBits']
84
- );
85
- const hashBuffer = await crypto.subtle.deriveBits(
86
- {
87
- name: 'PBKDF2',
88
- salt: salt_,
89
- iterations: iterations_,
90
- hash: 'SHA-256'
91
- },
92
- keyMaterial,
93
- 256
94
- );
95
- return new DataView(hashBuffer);
96
- """
1
+ capability Crypto {}
2
+
3
+ extend self: Crypto {
4
+
5
+ randomUuid(): String
6
+ target js async """
7
+ return self_.randomUUID();
8
+ """
9
+
10
+ randomBuffer(size: Int): Buffer {
11
+ let buffer = Buffer.new(size)
12
+ self.randomizeBuffer(buffer)
13
+ buffer
14
+ }
15
+
16
+ randomizeBuffer(buffer: Buffer): Unit
17
+ target js async """
18
+ self_.getRandomValues(new Uint8Array(buffer_.buffer, buffer_.byteOffset, buffer_.byteLength));
19
+ """
20
+
21
+ hmacSha256(key: Buffer, buffer: Buffer): Buffer
22
+ target js async """
23
+ const cryptoKey = await self_.subtle.importKey(
24
+ 'raw',
25
+ key_,
26
+ {name: 'HMAC', hash: {name: 'SHA-256'}},
27
+ false,
28
+ ['sign']
29
+ );
30
+ const signature = await self_.subtle.sign(
31
+ 'HMAC',
32
+ cryptoKey,
33
+ buffer_
34
+ );
35
+ return new DataView(signature);
36
+ """
37
+
38
+ sha256(buffer: Buffer): Buffer
39
+ target js async """
40
+ let hash = await self_.subtle.digest('SHA-256', buffer_);
41
+ return new DataView(hash);
42
+ """
43
+
44
+ hashPassword(password: String, iterations: Int = 600000): String {
45
+ let salt = self.randomBuffer(16)
46
+ let hash = internalHashPassword(self, salt, password.toBuffer(), iterations)
47
+ "$pbkdf2-sha256-hex$" + iterations + "$" + salt.toHex() + "$" + hash.toHex()
48
+ }
49
+
50
+ checkPassword(password: String, passwordHash: String): Bool {
51
+ passwordHash.split('$').{
52
+ | ["", "pbkdf2-sha256-hex", iterationsText, saltText, hashText] {
53
+ iterationsText.getInt() | Some(iterations)
54
+ } =>
55
+ let computedHash =
56
+ internalHashPassword(self, Buffer.fromHex(saltText), password.toBuffer(), iterations)
57
+ let hash = Buffer.fromHex(hashText)
58
+ self.constantTimeEquals(computedHash, hash)
59
+ | _ => False
60
+ }
61
+ }
62
+
63
+ constantTimeEquals(buffer1: Buffer, buffer2: Buffer): Bool {
64
+ if(buffer1.size() != buffer2.size()) {False} else:
65
+ mutable v = 0
66
+ mutable i = 0
67
+ while {i < buffer1.size()} {
68
+ v = v.bitOr(buffer1.grabUint8(i).bitXor(buffer2.grabUint8(i)))
69
+ i += 1
70
+ }
71
+ v == 0
72
+ }
73
+
74
+ }
75
+
76
+ internalHashPassword(system: Crypto, salt: Buffer, password: Buffer, iterations: Int): Buffer
77
+ target js async """
78
+ const keyMaterial = await crypto.subtle.importKey(
79
+ 'raw',
80
+ password_,
81
+ {name: 'PBKDF2'},
82
+ false,
83
+ ['deriveBits']
84
+ );
85
+ const hashBuffer = await crypto.subtle.deriveBits(
86
+ {
87
+ name: 'PBKDF2',
88
+ salt: salt_,
89
+ iterations: iterations_,
90
+ hash: 'SHA-256'
91
+ },
92
+ keyMaterial,
93
+ 256
94
+ );
95
+ return new DataView(hashBuffer);
96
+ """
package/core/Equal.ff CHANGED
@@ -1,36 +1,36 @@
1
- trait T: Equal {
2
- equals(x: T, y: T): Bool
3
- }
4
-
5
- notEquals[T: Equal](x: T, y: T): Bool {
6
- !equals(x, y)
7
- }
8
-
9
- instance Nothing: Equal {
10
- equals(x: Nothing, y: Nothing): Bool {True}
11
- }
12
-
13
- instance Bool: Equal {
14
- equals(x: Bool, y: Bool): Bool
15
- target js sync """return x_ === y_"""
16
- }
17
-
18
- instance Char: Equal {
19
- equals(x: Char, y: Char): Bool
20
- target js sync """return x_ === y_"""
21
- }
22
-
23
- instance Int: Equal {
24
- equals(x: Int, y: Int): Bool
25
- target js sync """return x_ === y_"""
26
- }
27
-
28
- instance Float: Equal {
29
- equals(x: Float, y: Float): Bool
30
- target js sync """return x_ === y_"""
31
- }
32
-
33
- instance String: Equal {
34
- equals(x: String, y: String): Bool
35
- target js sync """return x_ === y_"""
36
- }
1
+ trait T: Equal {
2
+ equals(x: T, y: T): Bool
3
+ }
4
+
5
+ notEquals[T: Equal](x: T, y: T): Bool {
6
+ !equals(x, y)
7
+ }
8
+
9
+ instance Nothing: Equal {
10
+ equals(x: Nothing, y: Nothing): Bool {True}
11
+ }
12
+
13
+ instance Bool: Equal {
14
+ equals(x: Bool, y: Bool): Bool
15
+ target js sync """return x_ === y_"""
16
+ }
17
+
18
+ instance Char: Equal {
19
+ equals(x: Char, y: Char): Bool
20
+ target js sync """return x_ === y_"""
21
+ }
22
+
23
+ instance Int: Equal {
24
+ equals(x: Int, y: Int): Bool
25
+ target js sync """return x_ === y_"""
26
+ }
27
+
28
+ instance Float: Equal {
29
+ equals(x: Float, y: Float): Bool
30
+ target js sync """return x_ === y_"""
31
+ }
32
+
33
+ instance String: Equal {
34
+ equals(x: String, y: String): Bool
35
+ target js sync """return x_ === y_"""
36
+ }