firefly-compiler 0.6.18 → 0.6.20
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/compiler/Bridge.ff +80 -0
- package/compiler/Builder.ff +0 -4
- package/compiler/Compiler.ff +0 -4
- package/compiler/DevelopMode.ff +14 -2
- package/compiler/JsEmitter.ff +0 -4
- package/compiler/Main.ff +5 -8
- package/core/BuildSystem.ff +48 -92
- package/fireflysite/Html.ff +67 -28
- package/lux/Lux.ff +77 -48
- package/output/js/ff/compiler/Bridge.mjs +157 -0
- package/output/js/ff/compiler/Bridge.mjs.map +47 -0
- package/output/js/ff/compiler/Builder.mjs +8 -8
- package/output/js/ff/compiler/Builder.mjs.map +2 -3
- package/output/js/ff/compiler/Compiler.mjs +8 -12
- package/output/js/ff/compiler/Compiler.mjs.map +3 -4
- package/output/js/ff/compiler/DevelopMode.mjs +28 -4
- package/output/js/ff/compiler/DevelopMode.mjs.map +8 -3
- package/output/js/ff/compiler/JsEmitter.mjs +8 -12
- package/output/js/ff/compiler/JsEmitter.mjs.map +3 -4
- package/output/js/ff/compiler/Main.mjs +12 -14
- package/output/js/ff/compiler/Main.mjs.map +5 -6
- package/output/js/ff/core/BuildSystem.mjs +76 -72
- package/output/js/ff/core/BuildSystem.mjs.map +30 -38
- package/package.json +1 -1
- package/vscode/package.json +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import Builder
|
|
2
|
+
import ModuleCache
|
|
3
|
+
|
|
4
|
+
setGlobalBridge(nodeSystem: NodeSystem) {
|
|
5
|
+
// To avoid having the generated code for buildMain depend on the Firefly compiler,
|
|
6
|
+
// we provide the bridge through a global symbol that is read by BuildSystem.internalBridge.
|
|
7
|
+
nodeSystem.js().globalThis()->"$firefly_bridge" = BuildSystemBridge(
|
|
8
|
+
internalCompile = {internalCompile(nodeSystem, _, _)}
|
|
9
|
+
internalBrowserCallEsBuild = {callEsBuildForBrowser(nodeSystem, _, _, _, _)}
|
|
10
|
+
)!
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
internalCompile(nodeSystem: NodeSystem, mainFiles: List[Path], target: String): Unit {
|
|
14
|
+
Builder.buildViaBuildSystem(
|
|
15
|
+
nodeSystem
|
|
16
|
+
nodeSystem.path(nodeSystem!->"fireflyPath_"?)
|
|
17
|
+
mainFiles
|
|
18
|
+
target
|
|
19
|
+
)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
callEsBuildForBrowser(
|
|
23
|
+
nodeSystem: NodeSystem
|
|
24
|
+
mainJsFiles: List[String]
|
|
25
|
+
outputPath: String
|
|
26
|
+
minify: Bool
|
|
27
|
+
sourceMap: Bool
|
|
28
|
+
): Unit {
|
|
29
|
+
let esbuild = Js.import("esbuild")
|
|
30
|
+
Js.await(esbuild->build(Js->(
|
|
31
|
+
entryPoints = mainJsFiles
|
|
32
|
+
bundle = True
|
|
33
|
+
minify = minify
|
|
34
|
+
sourcemap = sourceMap
|
|
35
|
+
platform = "browser"
|
|
36
|
+
target = "es2017"
|
|
37
|
+
outdir = outputPath
|
|
38
|
+
outExtension = Js.object().with(".js", ".bundle.js")
|
|
39
|
+
)))
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
callEsBuildForNode(
|
|
43
|
+
self: NodeSystem
|
|
44
|
+
mainJsFile: String
|
|
45
|
+
outputPath: String
|
|
46
|
+
minify: Bool
|
|
47
|
+
): Unit {
|
|
48
|
+
let esbuild = Js.import("esbuild")
|
|
49
|
+
Js.await(esbuild->build(Js->(
|
|
50
|
+
entryPoints = [mainJsFile]
|
|
51
|
+
bundle = True
|
|
52
|
+
minify = minify
|
|
53
|
+
sourcemap = True
|
|
54
|
+
platform = "node"
|
|
55
|
+
target = "es2017"
|
|
56
|
+
external = ["esbuild", "uws.js"]
|
|
57
|
+
loader = Js.object().with(".node", "copy")
|
|
58
|
+
outdir = outputPath
|
|
59
|
+
)))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
callEsBuildContextForNode(
|
|
63
|
+
self: NodeSystem
|
|
64
|
+
mainJsFile: String
|
|
65
|
+
outputPath: String
|
|
66
|
+
minify: Bool
|
|
67
|
+
): JsValue {
|
|
68
|
+
let esbuild = Js.import("esbuild")
|
|
69
|
+
Js.await(esbuild->context(Js->(
|
|
70
|
+
entryPoints = [mainJsFile]
|
|
71
|
+
bundle = True
|
|
72
|
+
minify = minify
|
|
73
|
+
sourcemap = True
|
|
74
|
+
platform = "node"
|
|
75
|
+
target = "es2017"
|
|
76
|
+
external = ["esbuild", "uws.js"]
|
|
77
|
+
loader = Js.object().with(".node", "copy")
|
|
78
|
+
outfile = outputPath
|
|
79
|
+
)))
|
|
80
|
+
}
|
package/compiler/Builder.ff
CHANGED
|
@@ -15,7 +15,6 @@ build(
|
|
|
15
15
|
emitTarget: EmitTarget
|
|
16
16
|
mainModules: List[ModuleKey]
|
|
17
17
|
resolvedDependencies: ResolvedDependencies
|
|
18
|
-
compilerModulePath: Option[Path]
|
|
19
18
|
jsOutputPath: Path
|
|
20
19
|
printMeasurements: Bool
|
|
21
20
|
moduleCache: ModuleCache
|
|
@@ -24,7 +23,6 @@ build(
|
|
|
24
23
|
let compiler = Compiler.new(
|
|
25
24
|
emitTarget
|
|
26
25
|
system.mainTask()
|
|
27
|
-
compilerModulePath
|
|
28
26
|
jsOutputPath
|
|
29
27
|
resolvedDependencies
|
|
30
28
|
Map.new()
|
|
@@ -107,7 +105,6 @@ buildViaBuildSystem(
|
|
|
107
105
|
emitTarget = EmitBrowser
|
|
108
106
|
mainModules = mainModuleKeys
|
|
109
107
|
resolvedDependencies = resolvedDependencies.ResolvedDependencies(packagePaths = fixedPackagePaths)
|
|
110
|
-
compilerModulePath = None
|
|
111
108
|
jsOutputPath = system.path(".firefly/output").slash(target)
|
|
112
109
|
printMeasurements = printMeasurements
|
|
113
110
|
moduleCache = moduleCache
|
|
@@ -156,7 +153,6 @@ check(
|
|
|
156
153
|
let compiler = Compiler.new(
|
|
157
154
|
EmitNode
|
|
158
155
|
system.mainTask()
|
|
159
|
-
None
|
|
160
156
|
package.root.slash(".firefly").slash("temporary")
|
|
161
157
|
fixedResolvedDependencies
|
|
162
158
|
virtualFiles
|
package/compiler/Compiler.ff
CHANGED
|
@@ -13,7 +13,6 @@ import LspHook
|
|
|
13
13
|
capability Compiler(
|
|
14
14
|
emitTarget: EmitTarget
|
|
15
15
|
task: Task
|
|
16
|
-
compilerModulePath: Option[Path]
|
|
17
16
|
jsOutputPath: Path
|
|
18
17
|
packagePaths: Map[PackagePair, Path]
|
|
19
18
|
singleFilePackages: Set[PackagePair]
|
|
@@ -27,7 +26,6 @@ capability Compiler(
|
|
|
27
26
|
new(
|
|
28
27
|
emitTarget: EmitTarget
|
|
29
28
|
task: Task
|
|
30
|
-
compilerModulePath: Option[Path]
|
|
31
29
|
jsOutputPath: Path
|
|
32
30
|
resolvedDependencies: ResolvedDependencies
|
|
33
31
|
virtualFiles: Map[String, String]
|
|
@@ -37,7 +35,6 @@ new(
|
|
|
37
35
|
Compiler(
|
|
38
36
|
emitTarget = emitTarget
|
|
39
37
|
task = task
|
|
40
|
-
compilerModulePath = compilerModulePath
|
|
41
38
|
jsOutputPath = jsOutputPath
|
|
42
39
|
packagePaths = resolvedDependencies.packagePaths
|
|
43
40
|
singleFilePackages = resolvedDependencies.singleFilePackages
|
|
@@ -231,7 +228,6 @@ extend self: Compiler {
|
|
|
231
228
|
otherModules = allModules
|
|
232
229
|
emitTarget = self.emitTarget
|
|
233
230
|
isMainModule = isMainModule
|
|
234
|
-
compilerModuleFileUrl = self.compilerModulePath.map {_.relativeUrlTo(jsPath)}
|
|
235
231
|
moduleKey = moduleKey
|
|
236
232
|
)
|
|
237
233
|
emitter.emitModule(module)
|
package/compiler/DevelopMode.ff
CHANGED
|
@@ -4,7 +4,8 @@ import Dependencies
|
|
|
4
4
|
import DependencyLock
|
|
5
5
|
import Syntax
|
|
6
6
|
import JsEmitter
|
|
7
|
-
import
|
|
7
|
+
import Bridge
|
|
8
|
+
import Builder
|
|
8
9
|
|
|
9
10
|
capability Runner(
|
|
10
11
|
lock: Lock
|
|
@@ -139,7 +140,7 @@ startApp(
|
|
|
139
140
|
)
|
|
140
141
|
let esBuildPath = runFilePath.parent().grab().slash(runFilePath.base() + ".minified.js")
|
|
141
142
|
let context = esbuildContext.jsValue.else {
|
|
142
|
-
let jsValue =
|
|
143
|
+
let jsValue = Bridge.callEsBuildContextForNode(system, startPath.absolute(), esBuildPath.absolute(), minify = True)
|
|
143
144
|
esbuildContext.jsValue = Some(jsValue)
|
|
144
145
|
jsValue
|
|
145
146
|
}
|
|
@@ -166,6 +167,17 @@ startApp(
|
|
|
166
167
|
runner.state = CompileErrorState(None, error.message())
|
|
167
168
|
}
|
|
168
169
|
}
|
|
170
|
+
} elseIf {message->ffDevelopMode === "internalBrowserCallEsBuild"} {
|
|
171
|
+
runner.lock.do {
|
|
172
|
+
if(taskIteration == runner.iteration):
|
|
173
|
+
try {
|
|
174
|
+
Bridge.callEsBuildForBrowser(system, message->mainJsFiles?, message->outputPath?, message->minify?, message->sourceMap?)
|
|
175
|
+
forkedProcess->send(Js->(ffDevelopMode = "internalBrowserCallEsBuild"))
|
|
176
|
+
Unit
|
|
177
|
+
} catchAny {error =>
|
|
178
|
+
runner.state = CompileErrorState(None, error.message())
|
|
179
|
+
}
|
|
180
|
+
}
|
|
169
181
|
}
|
|
170
182
|
}))
|
|
171
183
|
let standardOut = result.standardOut.toString()
|
package/compiler/JsEmitter.ff
CHANGED
|
@@ -8,7 +8,6 @@ class JsEmitter(
|
|
|
8
8
|
jsImporter: JsImporter
|
|
9
9
|
emitTarget: EmitTarget
|
|
10
10
|
isMainModule: Bool
|
|
11
|
-
compilerModuleFileUrl: Option[String]
|
|
12
11
|
moduleKey: ModuleKey
|
|
13
12
|
mutable emittingAsync: Bool
|
|
14
13
|
mutable tailCallUsed: Bool
|
|
@@ -29,7 +28,6 @@ new(
|
|
|
29
28
|
otherModules: List[Module]
|
|
30
29
|
emitTarget: EmitTarget
|
|
31
30
|
isMainModule: Bool
|
|
32
|
-
compilerModuleFileUrl: Option[String]
|
|
33
31
|
moduleKey: ModuleKey
|
|
34
32
|
): JsEmitter {
|
|
35
33
|
JsEmitter(
|
|
@@ -39,7 +37,6 @@ new(
|
|
|
39
37
|
jsImporter = JsImporter.new()
|
|
40
38
|
emitTarget = emitTarget
|
|
41
39
|
isMainModule = isMainModule
|
|
42
|
-
compilerModuleFileUrl = compilerModuleFileUrl
|
|
43
40
|
moduleKey = moduleKey
|
|
44
41
|
emittingAsync = False
|
|
45
42
|
tailCallUsed = False
|
|
@@ -121,7 +118,6 @@ extend self: JsEmitter {
|
|
|
121
118
|
emitModule(module: Module) {
|
|
122
119
|
let selfImport = self.emitImport(self.moduleKey)
|
|
123
120
|
let imports = [
|
|
124
|
-
self.compilerModuleFileUrl.map {"import * as $firefly_compiler from '" + _ + "'"}.toList()
|
|
125
121
|
module.imports.sortBy {_.moduleKey}.map {self.emitImport(_.moduleKey)}
|
|
126
122
|
].flatten()
|
|
127
123
|
let liner = Liner(self, True)
|
package/compiler/Main.ff
CHANGED
|
@@ -12,6 +12,7 @@ import ModuleCache
|
|
|
12
12
|
import LspHook
|
|
13
13
|
import DependencyLock
|
|
14
14
|
import DevelopMode
|
|
15
|
+
import Bridge
|
|
15
16
|
|
|
16
17
|
data MainCommand {
|
|
17
18
|
BootstrapCommand
|
|
@@ -108,7 +109,6 @@ main(system: NodeSystem): Unit {
|
|
|
108
109
|
].toMap()
|
|
109
110
|
singleFilePackages = [].toSet()
|
|
110
111
|
)
|
|
111
|
-
compilerModulePath = None
|
|
112
112
|
jsOutputPath = workingDirectory.slash("output").slash("js")
|
|
113
113
|
printMeasurements = True
|
|
114
114
|
moduleCache = ModuleCache.new(0)
|
|
@@ -176,9 +176,6 @@ buildScript(
|
|
|
176
176
|
} else {
|
|
177
177
|
resolvedDependencies.packagePaths.add(PackagePair("ff", "core"), fireflyPath.slash("core"))
|
|
178
178
|
}
|
|
179
|
-
let compilerModulePath = if(emitTarget != EmitBrowser) {
|
|
180
|
-
fireflyPath.slash("output").slash("js").slash("ff").slash("compiler/Builder.mjs")
|
|
181
|
-
}
|
|
182
179
|
let targetName = emitTarget.{
|
|
183
180
|
| EmitNode => "node"
|
|
184
181
|
| EmitBrowser => "browser"
|
|
@@ -192,7 +189,6 @@ buildScript(
|
|
|
192
189
|
emitTarget = emitTarget
|
|
193
190
|
mainModules = [moduleKey]
|
|
194
191
|
resolvedDependencies = resolvedDependencies.ResolvedDependencies(packagePaths = fixedPackagePaths)
|
|
195
|
-
compilerModulePath = compilerModulePath
|
|
196
192
|
jsOutputPath = system.path(".firefly").path("output").path(targetName)
|
|
197
193
|
printMeasurements = printMeasurements
|
|
198
194
|
moduleCache = moduleCache
|
|
@@ -286,7 +282,7 @@ bundleForExecutable(system: NodeSystem, packagePair: PackagePair, moduleKey: Mod
|
|
|
286
282
|
// The following should be awaited, but esbuild doesn't support top level await - still seems to work though
|
|
287
283
|
"run.$run$(null, process.argv.slice(2))"
|
|
288
284
|
)
|
|
289
|
-
|
|
285
|
+
Bridge.callEsBuildForNode(
|
|
290
286
|
system,
|
|
291
287
|
startPath.absolute(),
|
|
292
288
|
outputPath.absolute(),
|
|
@@ -298,8 +294,8 @@ bundleForBrowser(system: NodeSystem, packagePair: PackagePair, moduleKey: Module
|
|
|
298
294
|
let packagePath = moduleKey.packagePair.groupName("/")
|
|
299
295
|
let outputPath = system.path(".firefly/output/browser/" + packagePath + "/")
|
|
300
296
|
let runFile = outputPath.slash(moduleKey.importName() + ".run.mjs")
|
|
301
|
-
|
|
302
|
-
system
|
|
297
|
+
Bridge.callEsBuildForBrowser(
|
|
298
|
+
system
|
|
303
299
|
[runFile.absolute()]
|
|
304
300
|
outputPath.absolute()
|
|
305
301
|
minify = True
|
|
@@ -315,6 +311,7 @@ importAndRun(
|
|
|
315
311
|
arguments: List[String]
|
|
316
312
|
buildMode: Bool = False
|
|
317
313
|
): Bool {
|
|
314
|
+
Bridge.setGlobalBridge(system)
|
|
318
315
|
let runFile = locateRunFile(system, target, moduleKey)
|
|
319
316
|
let runFilePath = if(runFile.contains("://")) {system.pathFromUrl(runFile)} else {system.path(runFile)}
|
|
320
317
|
if(runFilePath.exists()) {
|
package/core/BuildSystem.ff
CHANGED
|
@@ -1,23 +1,29 @@
|
|
|
1
1
|
capability BuildSystem {}
|
|
2
2
|
|
|
3
|
+
capability BuildSystemBridge(
|
|
4
|
+
internalCompile: (List[Path], String) => Unit
|
|
5
|
+
internalBrowserCallEsBuild: (List[String], String, Bool, Bool) => Unit
|
|
6
|
+
)
|
|
7
|
+
|
|
3
8
|
extend self: BuildSystem {
|
|
4
9
|
|
|
5
10
|
compileForBrowser(mainFiles: List[String]): AssetSystem {
|
|
11
|
+
let bridge = internalBridge(self)
|
|
6
12
|
// TODO: Check that the mainFile is in the current package directory
|
|
7
|
-
internalCompile(
|
|
13
|
+
bridge.internalCompile(mainFiles.map {internalPath(self, _)}, "browser")
|
|
8
14
|
let streams = internalListDirectory(internalPath(self, ".firefly/output/browser"))
|
|
9
15
|
let mainPackagePair = internalMainPackagePair(self)
|
|
10
16
|
AssetSystem(streams.toMap())
|
|
11
17
|
}
|
|
12
18
|
|
|
13
19
|
bundleForBrowser(mainFiles: List[String], minify: Bool = True, sourceMaps: Bool = False): AssetSystem {
|
|
14
|
-
|
|
20
|
+
let bridge = internalBridge(self)
|
|
21
|
+
bridge.internalCompile(mainFiles.map {internalPath(self, _)}, "browser")
|
|
15
22
|
let browserOutputPath = internalPath(self, ".firefly/output/browser")
|
|
16
23
|
let runPaths = internalListPath(browserOutputPath).filter {_.base().endsWith(".run.mjs")}.toList()
|
|
17
24
|
if(Js.globalThis()->ffDevelopMode.typeof() == "undefined") {
|
|
18
25
|
let outputPath = runPaths.grabFirst().parent().grab()
|
|
19
|
-
|
|
20
|
-
internalBrowserCallEsBuild(self, runPaths.map {_.absolute()}, outputPath.absolute(), minify, sourceMaps)
|
|
26
|
+
bridge.internalBrowserCallEsBuild(runPaths.map {_.absolute()}, outputPath.absolute(), minify, sourceMaps)
|
|
21
27
|
let bundlePaths = runPaths.flatMap {p =>
|
|
22
28
|
let outputPath = p.parent().grab()
|
|
23
29
|
let bundlePath = outputPath.slash(p.base().removeLast(".mjs").grab() + ".bundle.js")
|
|
@@ -39,7 +45,7 @@ extend self: BuildSystem {
|
|
|
39
45
|
function bundle() {
|
|
40
46
|
lock.do {
|
|
41
47
|
if(!built.contains(p.absolute())) {
|
|
42
|
-
internalBrowserCallEsBuild(
|
|
48
|
+
bridge.internalBrowserCallEsBuild([p.absolute()], outputPath.absolute(), minify, sourceMaps)
|
|
43
49
|
built = built.add(p.absolute())
|
|
44
50
|
}
|
|
45
51
|
bundlePath.readStream()
|
|
@@ -85,66 +91,6 @@ extend self: BuildSystem {
|
|
|
85
91
|
|
|
86
92
|
}
|
|
87
93
|
|
|
88
|
-
internalBrowserCallEsBuild(
|
|
89
|
-
self: BuildSystem
|
|
90
|
-
mainJsFiles: List[String]
|
|
91
|
-
outputPath: String
|
|
92
|
-
minify: Bool
|
|
93
|
-
sourceMap: Bool
|
|
94
|
-
): Unit {
|
|
95
|
-
let esbuild = Js.import("esbuild")
|
|
96
|
-
Js.await(esbuild->build(Js->(
|
|
97
|
-
entryPoints = mainJsFiles
|
|
98
|
-
bundle = True
|
|
99
|
-
minify = minify
|
|
100
|
-
sourcemap = sourceMap
|
|
101
|
-
platform = "browser"
|
|
102
|
-
target = "es2017"
|
|
103
|
-
outdir = outputPath
|
|
104
|
-
outExtension = Js.object().with(".js", ".bundle.js")
|
|
105
|
-
)))
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
internalNodeCallEsBuild(
|
|
109
|
-
self: NodeSystem
|
|
110
|
-
mainJsFile: String
|
|
111
|
-
outputPath: String
|
|
112
|
-
minify: Bool
|
|
113
|
-
): Unit {
|
|
114
|
-
let esbuild = Js.import("esbuild")
|
|
115
|
-
Js.await(esbuild->build(Js->(
|
|
116
|
-
entryPoints = [mainJsFile]
|
|
117
|
-
bundle = True
|
|
118
|
-
minify = minify
|
|
119
|
-
sourcemap = True
|
|
120
|
-
platform = "node"
|
|
121
|
-
target = "es2017"
|
|
122
|
-
external = ["esbuild", "uws.js"]
|
|
123
|
-
loader = Js.object().with(".node", "copy")
|
|
124
|
-
outdir = outputPath
|
|
125
|
-
)))
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
internalNodeCallEsBuildContext(
|
|
129
|
-
self: NodeSystem
|
|
130
|
-
mainJsFile: String
|
|
131
|
-
outputPath: String
|
|
132
|
-
minify: Bool
|
|
133
|
-
): JsValue {
|
|
134
|
-
let esbuild = Js.import("esbuild")
|
|
135
|
-
Js.await(esbuild->context(Js->(
|
|
136
|
-
entryPoints = [mainJsFile]
|
|
137
|
-
bundle = True
|
|
138
|
-
minify = minify
|
|
139
|
-
sourcemap = True
|
|
140
|
-
platform = "node"
|
|
141
|
-
target = "es2017"
|
|
142
|
-
external = ["esbuild", "uws.js"]
|
|
143
|
-
loader = Js.object().with(".node", "copy")
|
|
144
|
-
outfile = outputPath
|
|
145
|
-
)))
|
|
146
|
-
}
|
|
147
|
-
|
|
148
94
|
internalListDirectory(path: Path): List[Pair[String, () => Stream[Buffer]]] {
|
|
149
95
|
function go(currentPath: Path): Stream[Path] {
|
|
150
96
|
currentPath.entries().flatMap {file =>
|
|
@@ -175,33 +121,6 @@ internalPath(buildSystem: BuildSystem, absoluteOrRelative: String): Path {
|
|
|
175
121
|
Path(nodePath->resolve(absoluteOrRelative)?)
|
|
176
122
|
}
|
|
177
123
|
|
|
178
|
-
internalCompile(buildSystem: BuildSystem, mainFiles: List[Path], target: String): Unit {
|
|
179
|
-
if(Js.globalThis()->ffDevelopMode.typeof() != "undefined") {
|
|
180
|
-
Js->process->send(Js->(
|
|
181
|
-
ffDevelopMode = "internalCompile"
|
|
182
|
-
mainFiles = mainFiles.map {_.absolute()}
|
|
183
|
-
target = target
|
|
184
|
-
))
|
|
185
|
-
Js.awaitCancellablePromise {resolve, reject, cleanup =>
|
|
186
|
-
Js->process->on("message", Js->{message =>
|
|
187
|
-
if(message->ffDevelopMode === "internalCompile") {
|
|
188
|
-
resolve(Unit) // Handle errors?
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
}
|
|
192
|
-
} else:
|
|
193
|
-
// Ported from the old FFI. It's quite fragile w.r.t. changes in code generation.
|
|
194
|
-
Js.await(Js.rawIdentifier("$firefly_compiler")->"buildViaBuildSystem_$"(
|
|
195
|
-
buildSystem!
|
|
196
|
-
internalPath(buildSystem, buildSystem!->"fireflyPath_"?)!
|
|
197
|
-
mainFiles!
|
|
198
|
-
target
|
|
199
|
-
Js.undefined()
|
|
200
|
-
Js.undefined()
|
|
201
|
-
Js.currentTask()!
|
|
202
|
-
))
|
|
203
|
-
}
|
|
204
|
-
|
|
205
124
|
internalMainPackagePair(buildSystem: BuildSystem): Pair[String, String] {
|
|
206
125
|
Pair(buildSystem!->"mainPackagePair_"->"group_"?, buildSystem!->"mainPackagePair_"->"name_"?)
|
|
207
126
|
}
|
|
@@ -227,3 +146,40 @@ internalReadAssets(system: NodeSystem): AssetSystem {
|
|
|
227
146
|
let streams = internalListDirectory(path)
|
|
228
147
|
AssetSystem(streams.toMap())
|
|
229
148
|
}
|
|
149
|
+
|
|
150
|
+
internalBridge(self: BuildSystem): BuildSystemBridge {
|
|
151
|
+
let bridge = Js->"$firefly_bridge"
|
|
152
|
+
if(!bridge.nullish()) {bridge?} else {
|
|
153
|
+
function delegate(job: String, message: JsValue): Unit {
|
|
154
|
+
Js->process->send(message.with("ffDevelopMode", job))
|
|
155
|
+
Js.awaitCancellablePromise {resolve, reject, cleanup =>
|
|
156
|
+
let callback = Js->{message =>
|
|
157
|
+
if(message->ffDevelopMode === job) {
|
|
158
|
+
resolve(Unit) // Handle errors?
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
cleanup {_ => Js->process->off("message", callback)}
|
|
162
|
+
Js->process->on("message", callback)
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
BuildSystemBridge(
|
|
166
|
+
internalCompile = {mainFiles, target =>
|
|
167
|
+
let message = Js->(
|
|
168
|
+
mainFiles = mainFiles.map {_.absolute()}
|
|
169
|
+
target = target
|
|
170
|
+
)
|
|
171
|
+
delegate("internalCompile", message)
|
|
172
|
+
}
|
|
173
|
+
internalBrowserCallEsBuild = {mainJsFiles, outputPath, minify, sourceMap =>
|
|
174
|
+
let message = Js->(
|
|
175
|
+
mainJsFiles = mainJsFiles
|
|
176
|
+
outputPath = outputPath
|
|
177
|
+
minify = minify
|
|
178
|
+
sourceMap = sourceMap
|
|
179
|
+
)
|
|
180
|
+
delegate("internalBrowserCallEsBuild", message)
|
|
181
|
+
}
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
package/fireflysite/Html.ff
CHANGED
|
@@ -4,35 +4,77 @@ import Lux from ff:lux
|
|
|
4
4
|
import Menu
|
|
5
5
|
|
|
6
6
|
serveHtml(
|
|
7
|
+
system: NodeSystem
|
|
7
8
|
moduleName: String
|
|
8
9
|
title: String
|
|
9
10
|
pageData: Buffer
|
|
10
|
-
contentHtml: String
|
|
11
|
-
styleTags: String
|
|
12
11
|
request: WebRequest[WebResponse]
|
|
12
|
+
body: Lux => Unit
|
|
13
13
|
): Unit {
|
|
14
|
+
let html = Lux.renderToString {lux, insertStyleTags =>
|
|
15
|
+
lux.add("html") {
|
|
16
|
+
lux.set("lang", "en")
|
|
17
|
+
lux.set("style", "background-color: #ffffff; color: #333333; width: 100%; height: 100%; color-scheme: light;")
|
|
18
|
+
lux.add("head") {
|
|
19
|
+
lux.add("title") {lux.text(title)}
|
|
20
|
+
lux.add("meta") {
|
|
21
|
+
lux.set("name", "viewport")
|
|
22
|
+
lux.set("content", "width=device-width, initial-scale=1.0")
|
|
23
|
+
}
|
|
24
|
+
lux.add("meta") {
|
|
25
|
+
lux.set("name", "theme-color")
|
|
26
|
+
lux.set("content", "#ecc45e")
|
|
27
|
+
}
|
|
28
|
+
lux.add("link") {
|
|
29
|
+
lux.set("rel", "modulepreload")
|
|
30
|
+
lux.set("href", "/js/ff/fireflysite/" + moduleName + ".run.mjs")
|
|
31
|
+
}
|
|
32
|
+
lux.add("link") {
|
|
33
|
+
lux.set("rel", "preload")
|
|
34
|
+
lux.set("href", "/assets/font/firefly-mono.woff2")
|
|
35
|
+
lux.set("as", "font")
|
|
36
|
+
lux.set("crossorigin", "anonymous")
|
|
37
|
+
}
|
|
38
|
+
lux.add("link") {
|
|
39
|
+
lux.set("rel", "preload")
|
|
40
|
+
lux.set("href", "/assets/font/firefly-sans.woff2")
|
|
41
|
+
lux.set("as", "font")
|
|
42
|
+
lux.set("crossorigin", "anonymous")
|
|
43
|
+
}
|
|
44
|
+
lux.add("link") {
|
|
45
|
+
lux.set("rel", "preload")
|
|
46
|
+
lux.set("href", "/assets/image/firefly-logo-yellow.webp")
|
|
47
|
+
lux.set("as", "image")
|
|
48
|
+
}
|
|
49
|
+
lux.add("style") {lux.text("@font-face { font-family: 'Firefly Mono'; font-display: fallback; src: url('/assets/font/firefly-mono.woff2'); }")}
|
|
50
|
+
lux.add("style") {lux.text("@font-face { font-family: 'Firefly Sans'; font-display: fallback; src: url('/assets/font/firefly-sans.woff2'); }")}
|
|
51
|
+
insertStyleTags()
|
|
52
|
+
lux.add("script") {
|
|
53
|
+
lux.set("type", "module")
|
|
54
|
+
lux.set("src", "/js/ff/fireflysite/" + moduleName + ".run.mjs")
|
|
55
|
+
}
|
|
56
|
+
lux.add("script") {
|
|
57
|
+
lux.set("type", "text/plain")
|
|
58
|
+
lux.set("id", "data")
|
|
59
|
+
lux.text(pageData.toLetter16())
|
|
60
|
+
}
|
|
61
|
+
lux.add("script") {
|
|
62
|
+
lux.set("type", "speculationrules")
|
|
63
|
+
lux.text(speculationRules)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
lux.add("body") {
|
|
67
|
+
lux.set("style", "margin: 0; padding: 0; width: 100%; height: 100%; touch-action: manipulation;")
|
|
68
|
+
lux.add("div") {
|
|
69
|
+
lux.set("id", "main")
|
|
70
|
+
body(lux)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
14
75
|
request.writeHeader("Content-Type", "text/html; charset=UTF-8")
|
|
15
76
|
request.writeText("<!doctype html>")
|
|
16
|
-
request.writeText(
|
|
17
|
-
request.writeText("<head>")
|
|
18
|
-
request.writeText("<title>" + title + "</title>")
|
|
19
|
-
request.writeText("<meta name='viewport' content='width=device-width, initial-scale=1.0'>")
|
|
20
|
-
request.writeText("<meta name='theme-color' content='#ecc45e'>")
|
|
21
|
-
request.writeText("<link rel='modulepreload' href='/js/ff/fireflysite/" + moduleName + ".run.mjs'>")
|
|
22
|
-
request.writeText("<link rel='preload' href='/assets/font/firefly-mono.woff2' as='font' crossorigin='anonymous'>")
|
|
23
|
-
request.writeText("<link rel='preload' href='/assets/font/firefly-sans.woff2' as='font' crossorigin='anonymous'>")
|
|
24
|
-
request.writeText("<link rel='preload' href='/assets/image/firefly-logo-yellow.webp' as='image'>")
|
|
25
|
-
request.writeText("<style>@font-face { font-family: 'Firefly Mono'; font-display: fallback; src: url('/assets/font/firefly-mono.woff2'); }</style>")
|
|
26
|
-
request.writeText("<style>@font-face { font-family: 'Firefly Sans'; font-display: fallback; src: url('/assets/font/firefly-sans.woff2'); }</style>")
|
|
27
|
-
request.writeText(styleTags)
|
|
28
|
-
request.writeText("<script type='module' src='/js/ff/fireflysite/" + moduleName + ".run.mjs'></script>")
|
|
29
|
-
request.writeText("<script type='text/plain' id='data'>" + pageData.toLetter16() + "</script>")
|
|
30
|
-
request.writeText(speculationRules)
|
|
31
|
-
request.writeText("</head>")
|
|
32
|
-
request.writeText("<body style='margin: 0; padding: 0; width: 100%; height: 100%; touch-action: manipulation;'>")
|
|
33
|
-
request.writeText("<div id='main'>" + contentHtml + "</div>")
|
|
34
|
-
request.writeText("</body>")
|
|
35
|
-
request.writeText("</html>")
|
|
77
|
+
request.writeText(html.first)
|
|
36
78
|
}
|
|
37
79
|
|
|
38
80
|
serve404(
|
|
@@ -55,8 +97,7 @@ renderAndServe[T: Serializable](
|
|
|
55
97
|
render: Lux => Unit
|
|
56
98
|
) {
|
|
57
99
|
let serialized = Serializable.serialize(pageData)
|
|
58
|
-
|
|
59
|
-
serveHtml(moduleName, title, serialized, htmlAndCss.first, htmlAndCss.second, request)
|
|
100
|
+
serveHtml(system, moduleName, title, serialized, request, render)
|
|
60
101
|
}
|
|
61
102
|
|
|
62
103
|
renderToMain[T: Serializable](system: BrowserSystem, render: (Lux, T) => Unit) {
|
|
@@ -67,13 +108,11 @@ renderToMain[T: Serializable](system: BrowserSystem, render: (Lux, T) => Unit) {
|
|
|
67
108
|
}
|
|
68
109
|
}
|
|
69
110
|
|
|
70
|
-
speculationRules: String = """
|
|
71
|
-
{
|
|
111
|
+
speculationRules: String = """{
|
|
72
112
|
"prerender": [{
|
|
73
113
|
"where": {
|
|
74
114
|
"href_matches": "/*"
|
|
75
115
|
},
|
|
76
116
|
"eagerness": "moderate"
|
|
77
117
|
}]
|
|
78
|
-
}
|
|
79
|
-
</script>"""
|
|
118
|
+
}"""
|