-
-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Begin migrate the web service app interface to JS-free infra
- Loading branch information
Showing
7 changed files
with
1,547 additions
and
126 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
using Pine.Core; | ||
using Pine.Elm019; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Collections.Immutable; | ||
using System.Linq; | ||
|
||
namespace Pine.Elm; | ||
|
||
public class ElmAppDependencyResolution | ||
{ | ||
public static IReadOnlyDictionary<IReadOnlyList<string>, ReadOnlyMemory<byte>> MergePackagesElmModules( | ||
IReadOnlyDictionary<IReadOnlyList<string>, ReadOnlyMemory<byte>> appSourceFiles) | ||
{ | ||
/* | ||
* TODO: select elm.json for the given entry point | ||
* */ | ||
|
||
var elmJsonFiles = | ||
appSourceFiles | ||
.Where(entry => entry.Key.Last() is "elm.json") | ||
.ToImmutableDictionary(); | ||
|
||
var elmJsonAggregateDependencies = | ||
elmJsonFiles | ||
.SelectMany(elmJsonFile => | ||
{ | ||
try | ||
{ | ||
var elmJsonParsed = | ||
System.Text.Json.JsonSerializer.Deserialize<ElmJsonStructure>(elmJsonFile.Value.Span); | ||
|
||
return | ||
new[] | ||
{ | ||
elmJsonParsed?.Dependencies.Direct, | ||
elmJsonParsed?.Dependencies.Indirect, | ||
elmJsonParsed?.Dependencies.Flat | ||
} | ||
.WhereNotNull(); | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.WriteLine("Failed to parse elm.json file: " + e); | ||
|
||
return []; | ||
} | ||
}) | ||
.SelectMany(dependency => dependency) | ||
.ToImmutableDictionary( | ||
keySelector: dependency => dependency.Key, | ||
elementSelector: | ||
dependency => | ||
{ | ||
var packageFiles = | ||
ElmPackageSource.LoadElmPackageAsync(dependency.Key, dependency.Value).Result; | ||
|
||
return packageFiles; | ||
}); | ||
|
||
var sourceElmModulesNames = | ||
appSourceFiles | ||
.Where(entry => entry.Key.Last().EndsWith(".elm", StringComparison.OrdinalIgnoreCase)) | ||
.Select(entry => ElmTime.ElmSyntax.ElmModule.ParseModuleName(entry.Value).WithDefault(null)) | ||
.WhereNotNull() | ||
.ToImmutableHashSet(EnumerableExtension.EqualityComparer<IReadOnlyList<string>>()); | ||
|
||
var packagesModulesNames = | ||
new HashSet<IReadOnlyList<string>>(EnumerableExtension.EqualityComparer<IReadOnlyList<string>>()); | ||
|
||
var sourceFilesWithMergedPackages = | ||
elmJsonAggregateDependencies | ||
.Aggregate( | ||
seed: appSourceFiles, | ||
func: (aggregate, package) => | ||
{ | ||
if (package.Key is "elm/core" || | ||
package.Key is "elm/json" || | ||
package.Key is "elm/bytes" || | ||
package.Key is "elm/parser") | ||
{ | ||
return aggregate; | ||
} | ||
|
||
var packageExposedModuleFiles = | ||
ElmPackage.ExposedModules(package.Value); | ||
|
||
return | ||
packageExposedModuleFiles | ||
.Aggregate( | ||
seed: aggregate.ToImmutableDictionary(), | ||
func: (innerAggregate, packageElmModuleFile) => | ||
{ | ||
var relativePath = packageElmModuleFile.Key; | ||
|
||
var moduleName = packageElmModuleFile.Value.moduleName; | ||
|
||
if (sourceElmModulesNames.Contains(moduleName)) | ||
{ | ||
Console.WriteLine( | ||
"Skipping Elm module file " + | ||
string.Join("/", relativePath) + | ||
" from package " + package.Key + " because it is already present in the source files."); | ||
|
||
return innerAggregate; | ||
} | ||
|
||
if (packagesModulesNames.Contains(moduleName)) | ||
{ | ||
Console.WriteLine( | ||
"Skipping Elm module file " + | ||
string.Join("/", relativePath) + | ||
" from package " + package.Key + " because it is already present in the packages."); | ||
|
||
return innerAggregate; | ||
} | ||
|
||
packagesModulesNames.Add(moduleName); | ||
|
||
return | ||
innerAggregate.SetItem( | ||
["dependencies", .. package.Key.Split('/'), .. packageElmModuleFile.Key], | ||
packageElmModuleFile.Value.fileContent); | ||
}); | ||
}); | ||
|
||
return sourceFilesWithMergedPackages; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
using Pine.Core; | ||
using Pine.PineVM; | ||
using System; | ||
using System.Collections.Concurrent; | ||
using System.Collections.Generic; | ||
|
||
namespace Pine.Elm.Platform; | ||
|
||
/// <summary> | ||
/// Mutating container for a web service app. | ||
/// </summary> | ||
public class MutatingWebServiceApp | ||
{ | ||
private readonly PineVMCache pineVMCache = new(); | ||
|
||
private readonly PineVM.PineVM pineVM; | ||
|
||
private readonly WebServiceInterface.WebServiceConfig appConfig; | ||
|
||
private PineValue appState; | ||
|
||
private readonly ConcurrentQueue<WebServiceInterface.Command> commands = new(); | ||
|
||
public IReadOnlyList<WebServiceInterface.Command> DequeueCommands() => | ||
[.. commands.DequeueAllEnumerable()]; | ||
|
||
public MutatingWebServiceApp( | ||
WebServiceInterface.WebServiceConfig appConfig) | ||
{ | ||
this.appConfig = appConfig; | ||
|
||
pineVM = new PineVM.PineVM(pineVMCache.EvalCache); | ||
|
||
appState = appConfig.Init.State; | ||
|
||
foreach (var command in appConfig.Init.Commands) | ||
{ | ||
commands.Enqueue(command); | ||
} | ||
} | ||
|
||
public WebServiceInterface.WebServiceEventResponse EventHttpRequest( | ||
WebServiceInterface.HttpRequestEventStruct httpRequest) | ||
{ | ||
var eventResponse = | ||
WebServiceInterface.WebServiceConfig.EventHttpRequest( | ||
appConfig, | ||
httpRequest, | ||
appState, | ||
pineVM); | ||
|
||
appState = eventResponse.State; | ||
|
||
MutateConsolidatingAppResponse(eventResponse); | ||
|
||
return eventResponse; | ||
} | ||
|
||
|
||
private void MutateConsolidatingAppResponse(WebServiceInterface.WebServiceEventResponse eventResponse) | ||
{ | ||
foreach (var cmd in eventResponse.Commands) | ||
{ | ||
commands.Enqueue(cmd); | ||
} | ||
} | ||
} |
Oops, something went wrong.