firefly-compiler 0.5.97 → 0.6.2

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/bin/firefly.js CHANGED
@@ -1,15 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  const path = require('path');
3
- const fs = require('fs');
4
3
  const { spawnSync } = require('child_process');
5
4
 
6
5
  const env = {
7
6
  ...process.env,
8
- NODE_PATH: path.join(require.resolve('esbuild'), '../../..'),
7
+ NODE_PATH: path.resolve(require.resolve('esbuild'), '../../..'),
9
8
  }
10
9
 
11
- console.log(env.NODE_PATH);
12
-
13
10
  const fireflyLink = path.resolve(__dirname, '../');
14
11
  const compilerPath = path.join(fireflyLink, 'output/js/ff/compiler/Main.run.mjs');
15
12
  const args = process.argv.slice(2);
@@ -26,4 +23,4 @@ try {
26
23
  });
27
24
  } catch (error) {
28
25
  process.exit(error.status || 1);
29
- }
26
+ }
@@ -201,6 +201,49 @@ extend self: JsEmitter {
201
201
  let targetMain = if(willRunOnNode) {"nodeMain"} else {"browserMain"}
202
202
  let mainFunction =
203
203
  functions.find {_.signature.name == targetMain}.orElse {functions.find {_.signature.name == "main"}}
204
+ function makeRunFunction(rawName: String, mainName: String, build: Bool, run: Bool): List[String] {
205
+ [
206
+ "export async function " + rawName + "(fireflyPath_, arguments_) {"
207
+ "Error.stackTraceLimit = 50"
208
+ "const $task = {controller_: new AbortController(), subtasks_: new Set(), promise_: new Promise(() => {}), started_: performance.now() * 0.001}"
209
+ ...if(self.emitTarget != EmitBrowser) {[
210
+ "let interval = setInterval(() => {}, 24 * 60 * 60 * 1000)" // To prevent deadlocks from exiting node
211
+ ]} else {[]}
212
+ "let system = {"
213
+ "task_: $task,"
214
+ "array_: arguments_,"
215
+ "fireflyPath_: fireflyPath_,"
216
+ "mainPackagePair_: {group_: \"" + mainPackagePair.group + "\", name_: \"" + mainPackagePair.name + "\"},"
217
+ "executableMode_: " + if(self.emitTarget == EmitExecutable) {"true"} else {"false"} + ","
218
+ "buildMode_: " + if(self.emitTarget == EmitBuild) {"true"} else {"false"}
219
+ "}"
220
+ "try {"
221
+ ...if(build && !buildMainFunction.isEmpty()) {[
222
+ "await buildMain_$(system, $task)"]
223
+ } else {[]}
224
+ ...if(build && self.emitTarget == EmitExecutable) {[
225
+ "if(system.assets_) await ff_core_BuildSystem.internalWriteAssets_$(system, system.assets_, $task)"
226
+ ]} else {[]}
227
+ ...if(run && self.emitTarget != EmitBuild) {[
228
+ ...if(self.emitTarget == EmitExecutable) {[
229
+ "system.assets_ = await ff_core_BuildSystem.internalReadAssets_$(system, $task)"
230
+ ]} else {[]}
231
+ "await " + mainName + "_$(system, $task)"
232
+ ]} else {[]}
233
+ ...if(!willRunOnNode) {[]} else {[
234
+ "} catch(error) {"
235
+ "console.error(ff_core_Error.Error_stack(error))"
236
+ "process.exit(1)"
237
+ ]}
238
+ "} finally {"
239
+ ...if(self.emitTarget != EmitBrowser) {[
240
+ "$task.controller_.abort()"
241
+ "clearInterval(interval)"
242
+ ]} else {[]}
243
+ "}"
244
+ "}"
245
+ ]
246
+ }
204
247
  mainFunction.map {_.signature.name}.map {mainName => [[
205
248
  ...buildMainFunction.map {buildMain =>
206
249
  "import {" + escapeKeyword(buildMain.signature.name) + "$} from './" + moduleName + ".mjs'"
@@ -208,42 +251,13 @@ extend self: JsEmitter {
208
251
  "import {" + escapeKeyword(mainName) + "$} from './" + moduleName + ".mjs'"
209
252
  self.emitImport(ModuleKey(PackagePair("ff", "core"), [], "Error"))
210
253
  self.emitImport(ModuleKey(PackagePair("ff", "core"), [], "BuildSystem"))
211
- "export async function $run$(fireflyPath_, arguments_) {"
212
- "Error.stackTraceLimit = 50"
213
- "const $task = {controller_: new AbortController(), subtasks_: new Set(), promise_: new Promise(() => {}), started_: performance.now() * 0.001}"
214
- ...if(self.emitTarget != EmitBrowser) {[
215
- "let interval = setInterval(() => {}, 24 * 60 * 60 * 1000)" // To prevent deadlocks from exiting node
216
- ]} else {[]}
217
- "let system = {"
218
- "task_: $task,"
219
- "array_: arguments_,"
220
- "fireflyPath_: fireflyPath_,"
221
- "mainPackagePair_: {group_: \"" + mainPackagePair.group + "\", name_: \"" + mainPackagePair.name + "\"},"
222
- "executableMode_: " + if(self.emitTarget == EmitExecutable) {"true"} else {"false"} + ","
223
- "buildMode_: " + if(self.emitTarget == EmitBuild) {"true"} else {"false"}
224
- "}"
225
- "try {"
226
- ...if(!buildMainFunction.isEmpty()) {[
227
- "await buildMain_$(system, $task)"]
228
- } else {[]}
229
- ...if(self.emitTarget != EmitBuild && self.emitTarget != EmitExecutable) {[
230
- "await " + mainName + "_$(system, $task)"
231
- ]} else {[]}
232
- ...if(self.emitTarget == EmitExecutable) {[
233
- "if(system.assets_) await ff_core_BuildSystem.internalWriteAssets_$(system, system.assets_, $task)"
234
- ]} else {[]}
235
- ...if(!willRunOnNode) {[]} else {[
236
- "} catch(error) {"
237
- "console.error(ff_core_Error.Error_stack(error))"
238
- "process.exit(1)"
239
- ]}
240
- "} finally {"
241
- ...if(self.emitTarget != EmitBrowser) {[
242
- "$task.controller_.abort()"
243
- "clearInterval(interval)"
244
- ]} else {[]}
245
- "}"
246
- "}"
254
+ ...self.emitTarget.{
255
+ | EmitExecutable => [
256
+ ...makeRunFunction("$build$", mainName = mainName, build = True, run = False)
257
+ ...makeRunFunction("$run$", mainName = mainName, build = False, run = True)
258
+ ]
259
+ | _ => makeRunFunction("$run$", mainName = mainName, build = True, run = True)
260
+ }
247
261
  ...self.emitTarget.{
248
262
  | EmitBrowser => [
249
263
  "queueMicrotask(async () => {"
package/compiler/Main.ff CHANGED
@@ -70,7 +70,7 @@ main(system: NodeSystem): Unit {
70
70
  let moduleKey =
71
71
  buildScript(system, mainPath, resolvedDependencies.mainPackagePair, EmitExecutable, resolvedDependencies)
72
72
  bundleForExecutable(system, resolvedDependencies.mainPackagePair, moduleKey)
73
- importAndRun(system, fireflyPath, "executable", moduleKey, [])
73
+ importAndRun(system, fireflyPath, "executable", moduleKey, [], buildMode = True)
74
74
 
75
75
  | CheckCommand(filePath) =>
76
76
  let errors = Builder.check(
@@ -280,9 +280,16 @@ bundleForExecutable(system: NodeSystem, packagePair: PackagePair, moduleKey: Mod
280
280
  let packagePath = moduleKey.packagePair.groupName("/")
281
281
  let outputPath = system.path(".firefly/output/executable/" + packagePath + "/")
282
282
  let runFile = outputPath.slash(moduleKey.importName() + ".run.mjs")
283
+ let startPath = runFile.parent().grab().slash(runFile.base() + ".start.mjs")
284
+ startPath.writeText(
285
+ "import * as run from " + Json.string("./" + runFile.base()).write() + "\n" +
286
+ "globalThis.ffDevelopMode = true\n" +
287
+ // The following should be awaited, but esbuild doesn't support top level await - still seems to work though
288
+ "run.$run$(null, process.argv.slice(2))"
289
+ )
283
290
  BuildSystem.internalNodeCallEsBuild(
284
291
  system,
285
- runFile.absolute(),
292
+ startPath.absolute(),
286
293
  outputPath.absolute(),
287
294
  minify = True
288
295
  )
@@ -307,12 +314,17 @@ importAndRun(
307
314
  target: String
308
315
  moduleKey: ModuleKey
309
316
  arguments: List[String]
317
+ buildMode: Bool = False
310
318
  ): Bool {
311
319
  let runFile = locateRunFile(system, target, moduleKey)
312
320
  let runFilePath = if(runFile.contains("://")) {system.pathFromUrl(runFile)} else {system.path(runFile)}
313
321
  if(runFilePath.exists()) {
314
322
  let main = Js.await(Js.dynamicImport(runFile))
315
- Js.await(main->"$run$"(fireflyPath.absolutePath, arguments))
323
+ if(buildMode) {
324
+ Js.await(main->"$build$"(fireflyPath.absolutePath, arguments))
325
+ } else {
326
+ Js.await(main->"$run$"(fireflyPath.absolutePath, arguments))
327
+ }
316
328
  True
317
329
  } else {
318
330
  False
@@ -96,7 +96,7 @@ internalBrowserCallEsBuild(
96
96
  minify: Bool
97
97
  sourceMap: Bool
98
98
  ): Unit {
99
- let esbuild = Js.import("esbuild/lib/main.js")
99
+ let esbuild = Js.import("esbuild")
100
100
  Js.await(esbuild->build(Js->(
101
101
  entryPoints = mainJsFiles
102
102
  bundle = True
@@ -115,7 +115,7 @@ internalNodeCallEsBuild(
115
115
  outputPath: String
116
116
  minify: Bool
117
117
  ): Unit {
118
- let esbuild = Js.import("esbuild/lib/main.js")
118
+ let esbuild = Js.import("esbuild")
119
119
  Js.await(esbuild->build(Js->(
120
120
  entryPoints = [mainJsFile]
121
121
  bundle = True
@@ -135,7 +135,7 @@ internalNodeCallEsBuildContext(
135
135
  outputPath: String
136
136
  minify: Bool
137
137
  ): JsValue {
138
- let esbuild = Js.import("esbuild/lib/main.js")
138
+ let esbuild = Js.import("esbuild")
139
139
  Js.await(esbuild->context(Js->(
140
140
  entryPoints = [mainJsFile]
141
141
  bundle = True
@@ -224,3 +224,10 @@ internalWriteAssets(system: NodeSystem, assetSystem: AssetSystem): Unit {
224
224
  }
225
225
  }
226
226
  }
227
+
228
+ internalReadAssets(system: NodeSystem): AssetSystem {
229
+ let path = system.path(".").slash(".firefly").path("output").slash("assets")
230
+ Log.debug("Reading assets from " + path.absolute())
231
+ let streams = internalListDirectory(path)
232
+ AssetSystem(streams.toMap())
233
+ }
@@ -6,6 +6,7 @@ WORKDIR /home/node/firefly
6
6
  RUN npm install firefly-compiler
7
7
  WORKDIR /home/node/app
8
8
  COPY --chown=node:node . .
9
+ RUN npm install esbuild
9
10
  RUN [ "/home/node/firefly/node_modules/.bin/firefly", "build", "Main.ff" ]
10
11
  EXPOSE 8080
11
12
  ENTRYPOINT [ "dumb-init", "node", "--harmony-temporal", ".firefly/output/executable/ff/fireflysite/Main.run.js", "0.0.0.0", "8080" ]
@@ -807,28 +807,40 @@ return ff_core_List.List_find(functions_, ((_w1) => {
807
807
  return (_w1.signature_.name_ === "main")
808
808
  }))
809
809
  }));
810
- return ff_core_Option.Option_else(ff_core_Option.Option_map(ff_core_Option.Option_map(mainFunction_, ((_w1) => {
811
- return _w1.signature_.name_
812
- })), ((mainName_) => {
813
- return [ff_core_List.List_join([...ff_core_Option.Option_toList(ff_core_Option.Option_map(buildMainFunction_, ((buildMain_) => {
814
- return (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(buildMain_.signature_.name_)) + "$} from './") + moduleName_) + ".mjs'")
815
- }))), (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(mainName_)) + "$} from './") + moduleName_) + ".mjs'"), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "Error")), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "BuildSystem")), "export async function $run$(fireflyPath_, arguments_) {", "Error.stackTraceLimit = 50", "const $task = {controller_: new AbortController(), subtasks_: new Set(), promise_: new Promise(() => {}), started_: performance.now() * 0.001}", ...(ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)
810
+ function makeRunFunction_(rawName_, mainName_, build_, run_) {
811
+ return [(("export async function " + rawName_) + "(fireflyPath_, arguments_) {"), "Error.stackTraceLimit = 50", "const $task = {controller_: new AbortController(), subtasks_: new Set(), promise_: new Promise(() => {}), started_: performance.now() * 0.001}", ...(ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)
816
812
  ? ["let interval = setInterval(() => {}, 24 * 60 * 60 * 1000)"]
817
813
  : []), "let system = {", "task_: $task,", "array_: arguments_,", "fireflyPath_: fireflyPath_,", (((("mainPackagePair_: {group_: \"" + mainPackagePair_.group_) + "\", name_: \"") + mainPackagePair_.name_) + "\"},"), (("executableMode_: " + (ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable())
818
814
  ? "true"
819
815
  : "false")) + ","), ("buildMode_: " + (ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBuild())
820
816
  ? "true"
821
- : "false")), "}", "try {", ...((!ff_core_Option.Option_isEmpty(buildMainFunction_))
817
+ : "false")), "}", "try {", ...((build_ && (!ff_core_Option.Option_isEmpty(buildMainFunction_)))
822
818
  ? ["await buildMain_$(system, $task)"]
823
- : []), ...((ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBuild(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget) && ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget))
824
- ? [(("await " + mainName_) + "_$(system, $task)")]
825
- : []), ...(ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable())
819
+ : []), ...((build_ && ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable()))
826
820
  ? ["if(system.assets_) await ff_core_BuildSystem.internalWriteAssets_$(system, system.assets_, $task)"]
821
+ : []), ...((run_ && ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBuild(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget))
822
+ ? [...(ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable())
823
+ ? ["system.assets_ = await ff_core_BuildSystem.internalReadAssets_$(system, $task)"]
824
+ : []), (("await " + mainName_) + "_$(system, $task)")]
827
825
  : []), ...((!willRunOnNode_)
828
826
  ? []
829
827
  : ["} catch(error) {", "console.error(ff_core_Error.Error_stack(error))", "process.exit(1)"]), "} finally {", ...(ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)
830
828
  ? ["$task.controller_.abort()", "clearInterval(interval)"]
831
- : []), "}", "}", ...(((_1) => {
829
+ : []), "}", "}"]
830
+ }
831
+ return ff_core_Option.Option_else(ff_core_Option.Option_map(ff_core_Option.Option_map(mainFunction_, ((_w1) => {
832
+ return _w1.signature_.name_
833
+ })), ((mainName_) => {
834
+ return [ff_core_List.List_join([...ff_core_Option.Option_toList(ff_core_Option.Option_map(buildMainFunction_, ((buildMain_) => {
835
+ return (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(buildMain_.signature_.name_)) + "$} from './") + moduleName_) + ".mjs'")
836
+ }))), (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(mainName_)) + "$} from './") + moduleName_) + ".mjs'"), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "Error")), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "BuildSystem")), ...(((_1) => {
837
+ if(_1.EmitExecutable) {
838
+ return [...makeRunFunction_("$build$", mainName_, true, false), ...makeRunFunction_("$run$", mainName_, false, true)]
839
+ }
840
+ {
841
+ return makeRunFunction_("$run$", mainName_, true, true)
842
+ }
843
+ }))(self_.emitTarget_), ...(((_1) => {
832
844
  if(_1.EmitBrowser) {
833
845
  return ["queueMicrotask(async () => {", "await $run$(null, [])", "})"]
834
846
  }
@@ -4416,28 +4428,40 @@ return ff_core_List.List_find(functions_, ((_w1) => {
4416
4428
  return (_w1.signature_.name_ === "main")
4417
4429
  }))
4418
4430
  }));
4419
- return ff_core_Option.Option_else(ff_core_Option.Option_map(ff_core_Option.Option_map(mainFunction_, ((_w1) => {
4420
- return _w1.signature_.name_
4421
- })), ((mainName_) => {
4422
- return [ff_core_List.List_join([...ff_core_Option.Option_toList(ff_core_Option.Option_map(buildMainFunction_, ((buildMain_) => {
4423
- return (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(buildMain_.signature_.name_)) + "$} from './") + moduleName_) + ".mjs'")
4424
- }))), (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(mainName_)) + "$} from './") + moduleName_) + ".mjs'"), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "Error")), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "BuildSystem")), "export async function $run$(fireflyPath_, arguments_) {", "Error.stackTraceLimit = 50", "const $task = {controller_: new AbortController(), subtasks_: new Set(), promise_: new Promise(() => {}), started_: performance.now() * 0.001}", ...(ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)
4431
+ function makeRunFunction_(rawName_, mainName_, build_, run_) {
4432
+ return [(("export async function " + rawName_) + "(fireflyPath_, arguments_) {"), "Error.stackTraceLimit = 50", "const $task = {controller_: new AbortController(), subtasks_: new Set(), promise_: new Promise(() => {}), started_: performance.now() * 0.001}", ...(ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)
4425
4433
  ? ["let interval = setInterval(() => {}, 24 * 60 * 60 * 1000)"]
4426
4434
  : []), "let system = {", "task_: $task,", "array_: arguments_,", "fireflyPath_: fireflyPath_,", (((("mainPackagePair_: {group_: \"" + mainPackagePair_.group_) + "\", name_: \"") + mainPackagePair_.name_) + "\"},"), (("executableMode_: " + (ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable())
4427
4435
  ? "true"
4428
4436
  : "false")) + ","), ("buildMode_: " + (ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBuild())
4429
4437
  ? "true"
4430
- : "false")), "}", "try {", ...((!ff_core_Option.Option_isEmpty(buildMainFunction_))
4438
+ : "false")), "}", "try {", ...((build_ && (!ff_core_Option.Option_isEmpty(buildMainFunction_)))
4431
4439
  ? ["await buildMain_$(system, $task)"]
4432
- : []), ...((ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBuild(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget) && ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget))
4433
- ? [(("await " + mainName_) + "_$(system, $task)")]
4434
- : []), ...(ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable())
4440
+ : []), ...((build_ && ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable()))
4435
4441
  ? ["if(system.assets_) await ff_core_BuildSystem.internalWriteAssets_$(system, system.assets_, $task)"]
4442
+ : []), ...((run_ && ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBuild(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget))
4443
+ ? [...(ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget.equals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitExecutable())
4444
+ ? ["system.assets_ = await ff_core_BuildSystem.internalReadAssets_$(system, $task)"]
4445
+ : []), (("await " + mainName_) + "_$(system, $task)")]
4436
4446
  : []), ...((!willRunOnNode_)
4437
4447
  ? []
4438
4448
  : ["} catch(error) {", "console.error(ff_core_Error.Error_stack(error))", "process.exit(1)"]), "} finally {", ...(ff_core_Equal.notEquals_(self_.emitTarget_, ff_compiler_JsEmitter.EmitBrowser(), ff_compiler_JsEmitter.ff_core_Equal_Equal$ff_compiler_JsEmitter_EmitTarget)
4439
4449
  ? ["$task.controller_.abort()", "clearInterval(interval)"]
4440
- : []), "}", "}", ...(((_1) => {
4450
+ : []), "}", "}"]
4451
+ }
4452
+ return ff_core_Option.Option_else(ff_core_Option.Option_map(ff_core_Option.Option_map(mainFunction_, ((_w1) => {
4453
+ return _w1.signature_.name_
4454
+ })), ((mainName_) => {
4455
+ return [ff_core_List.List_join([...ff_core_Option.Option_toList(ff_core_Option.Option_map(buildMainFunction_, ((buildMain_) => {
4456
+ return (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(buildMain_.signature_.name_)) + "$} from './") + moduleName_) + ".mjs'")
4457
+ }))), (((("import {" + ff_compiler_JsEmitter.escapeKeyword_(mainName_)) + "$} from './") + moduleName_) + ".mjs'"), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "Error")), ff_compiler_JsEmitter.JsEmitter_emitImport(self_, ff_compiler_Syntax.ModuleKey(ff_compiler_Syntax.PackagePair("ff", "core"), [], "BuildSystem")), ...(((_1) => {
4458
+ if(_1.EmitExecutable) {
4459
+ return [...makeRunFunction_("$build$", mainName_, true, false), ...makeRunFunction_("$run$", mainName_, false, true)]
4460
+ }
4461
+ {
4462
+ return makeRunFunction_("$run$", mainName_, true, true)
4463
+ }
4464
+ }))(self_.emitTarget_), ...(((_1) => {
4441
4465
  if(_1.EmitBrowser) {
4442
4466
  return ["queueMicrotask(async () => {", "await $run$(null, [])", "})"]
4443
4467
  }