public LiveProject(Fusion.IDocument fusionDocument, IFileSystem shell, IObservable <BytecodeGenerated> bytecodeGenerated, IScheduler scheduler = null) { scheduler = scheduler ?? Scheduler.Default; _shell = shell; var mutations = new Subject <IBinaryMessage>(); var idToElement = new BehaviorSubject <Dictionary <ObjectIdentifier, IElement> >(new Dictionary <ObjectIdentifier, IElement>()); var metadata = bytecodeGenerated .Select(bc => bc.Bytecode.Metadata.ElementTypeHierarchy.ToLookup()) .StartWith(Lookup.Empty <ObjectIdentifier, ObjectIdentifier>()) .Replay(1); _idToElement = idToElement; metadata.Connect(); bytecodeGenerated.Subscribe(bc => { var elements = idToElement.Value; foreach (var type in bc.Bytecode.Metadata.PrecompiledElements) { IElement element; if (!elements.TryGetValue(type.Id, out element)) { elements[type.Id] = element = new LiveElement( AbsoluteFilePath.Parse("N/A"), metadata, Observable.Return(true), new Subject <Unit>(), Observer.Create <IBinaryMessage>(_ => { }), getElement: GetElement); } element.Replace(_ => Task.FromResult(SourceFragment.FromString(type.Source))).Wait(); } idToElement.OnNext(elements); }); var unoProj = ProjectWatcher.Create(fusionDocument, shell, scheduler); Name = unoProj.Name; PackageReferences = unoProj.PackageReferences; ProjectReferences = unoProj.ProjectReferences; var liveDocuments = unoProj.UxFiles .CachePerElement(e => LiveDocument.Open(e, shell, metadata, idToElement, mutations, scheduler), val => val.Dispose()) .Select(ImmutableList.CreateRange) .Replay(1).RefCount(); var filePath = fusionDocument.FilePath.NotNone(); FilePath = filePath; RootDirectory = filePath.Select(f => f.ContainingDirectory); BuildOutputDirectory = unoProj.BuildOutputDirectory; _liveDocuments = liveDocuments; Mutations = mutations; BundleFiles = unoProj.BundleFiles; FuseJsFiles = unoProj.FuseJsFiles; Documents = liveDocuments.Select(d => ImmutableList.ToImmutableList(d.Cast <IDocument>())); var allElements = Documents .CachePerElement(doc => doc.Elements) .Select(docs => docs.ToObservableEnumerable()).Switch() .Select(e => e.Join().ToArray()) .Replay(1).RefCount(); var classes = allElements .Where(e => e.HasProperty("ux:Class")) .DistinctUntilSetChanged() .Replay(1); var globals = allElements .Where(e => e.HasProperty("ux:Global")) .DistinctUntilSetChanged() .Replay(1); Classes = classes; GlobalElements = globals; LogMessages = _liveDocuments.Switch(docs => docs.Select(doc => doc.Errors.NotNone().Select(o => doc.SimulatorIdPrefix + ": " + o.Message)) .Merge()); _garbage = Disposable.Combine( classes.Connect(), globals.Connect(), Disposable.Create(() => liveDocuments .FirstAsync() .Subscribe(documents => documents.Each(d => d.Dispose())))); var app = Documents .SelectPerElement(d => d.Root) .WherePerElement(e => e.Name.Is("App")) .Select(e => e.FirstOr(Element.Empty)) .Switch(); Context = new Context(app, GetElement); }