UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

1 lines 8.29 kB
import*as Common from"../../core/common/common.js";import*as Host from"../../core/host/host.js";import*as Platform from"../../core/platform/platform.js";import*as SDK from"../../core/sdk/sdk.js";import*as Components from"../../ui/legacy/components/utils/utils.js";import*as Bindings from"../bindings/bindings.js";import*as BreakpointManager from"../breakpoints/breakpoints.js";import*as Workspace from"../workspace/workspace.js";import{Automapping}from"./Automapping.js";import{LinkDecorator}from"./PersistenceUtils.js";let persistenceInstance;export class PersistenceImpl extends Common.ObjectWrapper.ObjectWrapper{workspace;breakpointManager;filePathPrefixesToBindingCount;subscribedBindingEventListeners;mapping;constructor(e,t){super(),this.workspace=e,this.breakpointManager=t,this.breakpointManager.addUpdateBindingsCallback(this.#e.bind(this)),this.filePathPrefixesToBindingCount=new FilePathPrefixesBindingCounts,this.subscribedBindingEventListeners=new Platform.MapUtilities.Multimap;const n=new LinkDecorator(this);Components.Linkifier.Linkifier.setLinkDecorator(n),this.mapping=new Automapping(this.workspace,this.onStatusAdded.bind(this),this.onStatusRemoved.bind(this))}static instance(e={forceNew:null,workspace:null,breakpointManager:null}){const{forceNew:t,workspace:n,breakpointManager:i}=e;if(!persistenceInstance||t){if(!n||!i)throw new Error("Missing arguments for workspace");persistenceInstance=new PersistenceImpl(n,i)}return persistenceInstance}addNetworkInterceptor(e){this.mapping.addNetworkInterceptor(e)}refreshAutomapping(){this.mapping.scheduleRemap()}async addBinding(e){await this.innerAddBinding(e)}async addBindingForTest(e){await this.innerAddBinding(e)}async removeBinding(e){await this.innerRemoveBinding(e)}async removeBindingForTest(e){await this.innerRemoveBinding(e)}#e(e){return e.project().type()!==Workspace.Workspace.projectTypes.Network?Promise.resolve():this.mapping.computeNetworkStatus(e)}async innerAddBinding(e){bindings.set(e.network,e),bindings.set(e.fileSystem,e),e.fileSystem.forceLoadOnCheckContent(),e.network.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this.onWorkingCopyCommitted,this),e.fileSystem.addEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this.onWorkingCopyCommitted,this),e.network.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this.onWorkingCopyChanged,this),e.fileSystem.addEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this.onWorkingCopyChanged,this),this.filePathPrefixesToBindingCount.add(e.fileSystem.url()),await this.moveBreakpoints(e.fileSystem,e.network),console.assert(!e.fileSystem.isDirty()||!e.network.isDirty()),e.fileSystem.isDirty()?this.syncWorkingCopy(e.fileSystem):e.network.isDirty()?this.syncWorkingCopy(e.network):e.network.hasCommits()&&e.network.content()!==e.fileSystem.content()&&(e.network.setWorkingCopy(e.network.content()),this.syncWorkingCopy(e.network)),this.notifyBindingEvent(e.network),this.notifyBindingEvent(e.fileSystem),this.dispatchEventToListeners(Events.BindingCreated,e)}async innerRemoveBinding(e){bindings.get(e.network)===e&&(console.assert(bindings.get(e.network)===bindings.get(e.fileSystem),"ERROR: inconsistent binding for networkURL "+e.network.url()),bindings.delete(e.network),bindings.delete(e.fileSystem),e.network.removeEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this.onWorkingCopyCommitted,this),e.fileSystem.removeEventListener(Workspace.UISourceCode.Events.WorkingCopyCommitted,this.onWorkingCopyCommitted,this),e.network.removeEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this.onWorkingCopyChanged,this),e.fileSystem.removeEventListener(Workspace.UISourceCode.Events.WorkingCopyChanged,this.onWorkingCopyChanged,this),this.filePathPrefixesToBindingCount.remove(e.fileSystem.url()),await this.breakpointManager.copyBreakpoints(e.network,e.fileSystem),this.notifyBindingEvent(e.network),this.notifyBindingEvent(e.fileSystem),this.dispatchEventToListeners(Events.BindingRemoved,e))}onStatusAdded(e){const t=new PersistenceBinding(e.network,e.fileSystem);return statusBindings.set(e,t),this.innerAddBinding(t)}async onStatusRemoved(e){const t=statusBindings.get(e);await this.innerRemoveBinding(t)}onWorkingCopyChanged(e){const t=e.data;this.syncWorkingCopy(t)}syncWorkingCopy(e){const t=bindings.get(e);if(!t||mutedWorkingCopies.has(t))return;const n=t.network===e?t.fileSystem:t.network;if(!e.isDirty())return mutedWorkingCopies.add(t),n.resetWorkingCopy(),mutedWorkingCopies.delete(t),void this.contentSyncedForTest();const i=Bindings.NetworkProject.NetworkProject.targetForUISourceCode(t.network);if(i&&i.type()===SDK.Target.Type.Node){const t=e.workingCopy();n.requestContent().then((()=>{const e=PersistenceImpl.rewrapNodeJSContent(n,n.workingCopy(),t);o.call(this,(()=>e))}))}else o.call(this,(()=>e.workingCopy()));function o(e){t&&mutedWorkingCopies.add(t),n.setWorkingCopyGetter(e),t&&mutedWorkingCopies.delete(t),this.contentSyncedForTest()}}onWorkingCopyCommitted(e){const t=e.data.uiSourceCode,n=e.data.content;this.syncContent(t,n,Boolean(e.data.encoded))}syncContent(e,t,n){const i=bindings.get(e);if(!i||mutedCommits.has(i))return;const o=i.network===e?i.fileSystem:i.network,s=Bindings.NetworkProject.NetworkProject.targetForUISourceCode(i.network);function r(e){i&&mutedCommits.add(i),o.setContent(e,n),i&&mutedCommits.delete(i),this.contentSyncedForTest()}s&&s.type()===SDK.Target.Type.Node?o.requestContent().then((e=>{const n=PersistenceImpl.rewrapNodeJSContent(o,e.content||"",t);r.call(this,n)})):r.call(this,t)}static rewrapNodeJSContent(e,t,n){return e.project().type()===Workspace.Workspace.projectTypes.FileSystem?(n.startsWith(NodePrefix)&&n.endsWith(NodeSuffix)&&(n=n.substring(NodePrefix.length,n.length-NodeSuffix.length)),t.startsWith(NodeShebang)&&(n=NodeShebang+n)):(n.startsWith(NodeShebang)&&(n=n.substring(NodeShebang.length)),t.startsWith(NodePrefix)&&t.endsWith(NodeSuffix)&&(n=NodePrefix+n+NodeSuffix)),n}contentSyncedForTest(){}async moveBreakpoints(e,t){const n=this.breakpointManager.breakpointLocationsForUISourceCode(e).map((e=>e.breakpoint));await Promise.all(n.map((async e=>(await e.remove(!1),this.breakpointManager.setBreakpoint(t,e.lineNumber(),e.columnNumber(),e.condition(),e.enabled(),e.isLogpoint(),"RESTORED")))))}hasUnsavedCommittedChanges(e){return!this.workspace.hasResourceContentTrackingExtensions()&&(!e.project().canSetFileContent()&&(!bindings.has(e)&&Boolean(e.hasCommits())))}binding(e){return bindings.get(e)||null}subscribeForBindingEvent(e,t){this.subscribedBindingEventListeners.set(e,t)}unsubscribeFromBindingEvent(e,t){this.subscribedBindingEventListeners.delete(e,t)}notifyBindingEvent(e){if(!this.subscribedBindingEventListeners.has(e))return;const t=Array.from(this.subscribedBindingEventListeners.get(e));for(const e of t)e.call(null)}fileSystem(e){const t=this.binding(e);return t?t.fileSystem:null}network(e){const t=this.binding(e);return t?t.network:null}filePathHasBindings(e){return this.filePathPrefixesToBindingCount.hasBindingPrefix(e)}}class FilePathPrefixesBindingCounts{prefixCounts;constructor(){this.prefixCounts=new Map}getPlatformCanonicalFilePath(e){return Host.Platform.isWin()?Common.ParsedURL.ParsedURL.toLowerCase(e):e}add(e){e=this.getPlatformCanonicalFilePath(e);let t="";for(const n of e.split("/")){t+=n+"/";const e=this.prefixCounts.get(t)||0;this.prefixCounts.set(t,e+1)}}remove(e){e=this.getPlatformCanonicalFilePath(e);let t="";for(const n of e.split("/")){t+=n+"/";const e=this.prefixCounts.get(t);1===e?this.prefixCounts.delete(t):void 0!==e&&this.prefixCounts.set(t,e-1)}}hasBindingPrefix(e){return(e=this.getPlatformCanonicalFilePath(e)).endsWith("/")||(e=Common.ParsedURL.ParsedURL.concatenate(e,"/")),this.prefixCounts.has(e)}}const bindings=new WeakMap,statusBindings=new WeakMap,mutedCommits=new WeakSet,mutedWorkingCopies=new WeakSet;export const NodePrefix="(function (exports, require, module, __filename, __dirname) { ";export const NodeSuffix="\n});";export const NodeShebang="#!/usr/bin/env node";export var Events;!function(e){e.BindingCreated="BindingCreated",e.BindingRemoved="BindingRemoved"}(Events||(Events={}));export class PersistenceBinding{network;fileSystem;constructor(e,t){this.network=e,this.fileSystem=t}}