Archived
deploy.
This commit is contained in:
@@ -0,0 +1,428 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Session State | HiAPI-C# 2025 </title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="title" content="Session State | HiAPI-C# 2025 ">
|
||||
|
||||
|
||||
<link rel="icon" href="../../img/HiAPI.favicon.ico">
|
||||
<link rel="stylesheet" href="../../public/docfx.min.css">
|
||||
<link rel="stylesheet" href="../../public/main.css">
|
||||
<meta name="docfx:navrel" content="../../toc.html">
|
||||
<meta name="docfx:tocrel" content="toc.html">
|
||||
|
||||
<meta name="docfx:rel" content="../../">
|
||||
|
||||
|
||||
|
||||
<meta name="loc:inThisArticle" content="In this article">
|
||||
<meta name="loc:searchResultsCount" content="{count} results for "{query}"">
|
||||
<meta name="loc:searchNoResults" content="No results for "{query}"">
|
||||
<meta name="loc:tocFilter" content="Filter by title">
|
||||
<meta name="loc:nextArticle" content="Next">
|
||||
<meta name="loc:prevArticle" content="Previous">
|
||||
<meta name="loc:themeLight" content="Light">
|
||||
<meta name="loc:themeDark" content="Dark">
|
||||
<meta name="loc:themeAuto" content="Auto">
|
||||
<meta name="loc:changeTheme" content="Change theme">
|
||||
<meta name="loc:copy" content="Copy">
|
||||
<meta name="loc:downloadPdf" content="Download PDF">
|
||||
|
||||
<script type="module" src="./../../public/docfx.min.js"></script>
|
||||
|
||||
<script>
|
||||
const theme = localStorage.getItem('theme') || 'auto'
|
||||
document.documentElement.setAttribute('data-bs-theme', theme === 'auto' ? (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light') : theme)
|
||||
</script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="tex2jax_ignore" data-layout="" data-yaml-mime="">
|
||||
<header class="bg-body border-bottom">
|
||||
<nav id="autocollapse" class="navbar navbar-expand-md" role="navigation">
|
||||
<div class="container-xxl flex-nowrap">
|
||||
<a class="navbar-brand" href="../../index.html">
|
||||
<img id="logo" class="svg" src="../../img/HiAPI.logo.png" alt="">
|
||||
|
||||
</a>
|
||||
<button class="btn btn-lg d-md-none border-0" type="button" data-bs-toggle="collapse" data-bs-target="#navpanel" aria-controls="navpanel" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<i class="bi bi-three-dots"></i>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navpanel">
|
||||
<div id="navbar">
|
||||
<form class="search" role="search" id="search">
|
||||
<i class="bi bi-search"></i>
|
||||
<input class="form-control" id="search-query" type="search" disabled placeholder="Search" autocomplete="off" aria-label="Search">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main class="container-xxl">
|
||||
<div class="toc-offcanvas">
|
||||
<div class="offcanvas-md offcanvas-start" tabindex="-1" id="tocOffcanvas" aria-labelledby="tocOffcanvasLabel">
|
||||
<div class="offcanvas-header">
|
||||
<h5 class="offcanvas-title" id="tocOffcanvasLabel">Table of Contents</h5>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="offcanvas" data-bs-target="#tocOffcanvas" aria-label="Close"></button>
|
||||
</div>
|
||||
<div class="offcanvas-body">
|
||||
<nav class="toc" id="toc"></nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
<div class="actionbar">
|
||||
<button class="btn btn-lg border-0 d-md-none" type="button" data-bs-toggle="offcanvas" data-bs-target="#tocOffcanvas" aria-controls="tocOffcanvas" aria-expanded="false" aria-label="Show table of contents">
|
||||
<i class="bi bi-list"></i>
|
||||
</button>
|
||||
|
||||
<nav id="breadcrumb"></nav>
|
||||
</div>
|
||||
|
||||
<article data-uid="Anatomy-SessionState">
|
||||
<h1 id="session-state">Session State</h1>
|
||||
|
||||
<p>Session state is what the web client still holds after the user moves from one screen to the next. It
|
||||
owns no route: the mechanism lives in the shell that wraps every route under <code>/</code> — a router outlet
|
||||
inside a <code><keep-alive></code> keyed on a project epoch — together with four Pinia stores, a family of
|
||||
module-level composables that deliberately sit outside the page lifecycle, and three browser storage
|
||||
keys. Every value in the client answers the same three questions: does it survive a navigation, does
|
||||
it survive a project change, and does it survive a browser reload.</p>
|
||||
<h2 id="the-project-epoch">The Project Epoch</h2>
|
||||
<p><code>MainLayout.vue</code> renders the routed page inside a <code><keep-alive></code> whose <code>:key</code> is <code>projectEpoch</code>. That
|
||||
epoch is a plain integer <code>ref</code> declared in the layout component itself — it is not a store value, it
|
||||
is not provided to anything, and nothing outside the file reads it. Two watchers in the same file are
|
||||
the only writers, and each adds one to it: a watcher on the project store's <code>projectPath</code>, and a
|
||||
watcher on the project store's <code>projectVersion</code>.</p>
|
||||
<p>The key sits on the <code><keep-alive></code> element rather than on the page component inside it. Changing it
|
||||
therefore discards the cache itself along with every page instance held in it and builds a fresh one,
|
||||
which is why a page may rely on its own mount hook and never watch the project: both Control-Tree
|
||||
pages call their host's <code>initialize()</code> from <code>onMounted</code>, and that runs once per project rather than
|
||||
once per visit.</p>
|
||||
<p>The two inputs move for different reasons.</p>
|
||||
<ul>
|
||||
<li><strong><code>projectPath</code></strong> is hydrated once at boot by the store's status fetch, assigned by New, Load and
|
||||
Save As from the response each returns, cleared outright by Close, and driven thereafter by a
|
||||
watcher inside the project store on the shared execution-status hub's status payload. A project
|
||||
change made in another tab, from a different browser, or outside the browser altogether therefore
|
||||
bumps the epoch here as well — and so, once, does the boot hydration on a service that already has
|
||||
a project open.</li>
|
||||
<li><strong><code>projectVersion</code></strong> is a counter the store raises in exactly one place: ReLoad. The backend raises
|
||||
its project-changed event with the path it already had, so the broadcast cannot be told apart from
|
||||
a no-op; the client-side counter is what makes a reload remount.</li>
|
||||
</ul>
|
||||
<p>Save on the current path moves neither, so it does not remount. The epoch only counts up, and because
|
||||
it lives in the layout it starts again at zero on a browser reload — nothing reads its value, only its
|
||||
transitions.</p>
|
||||
<h2 id="what-a-navigation-costs">What a Navigation Costs</h2>
|
||||
<p>The <code><keep-alive></code> carries no <code>include</code>, <code>exclude</code> or <code>max</code>, so every page reached under <code>/</code> is cached
|
||||
until the epoch changes. Leaving a route deactivates its component instead of unmounting it, and
|
||||
returning re-activates the same instance with its in-flight edits and its Control-Tree host intact.
|
||||
Scroll offsets are not part of that: the router's <code>scrollBehavior</code> resolves every navigation to the
|
||||
top of the page, and nothing saves an inner scroll position across a deactivation. The two routes
|
||||
declared outside the layout — the login screen and the not-found catch-all — are not cached at all.</p>
|
||||
<p>Three consequences the pages are written around:</p>
|
||||
<ul>
|
||||
<li>A cached page's watchers keep firing while another page is showing. The Control-Tree host compares
|
||||
the current route name against the one its scope owns before it writes the <code>?tree=</code> query back, so
|
||||
an off-screen host cannot rewrite the visible page's URL.</li>
|
||||
<li>A global listener has to be dropped on deactivation, not on unmount. The Execution transport binds
|
||||
its F5–F8 shortcuts on mount and on activation and removes them on deactivation and unmount, so on
|
||||
any other page F5 falls back to the browser's own reload instead of starting the run.</li>
|
||||
<li>The Execution, General Setup and Tool House pages each track their own activation in a flag that
|
||||
feeds the rendering canvas's <code>active</code> prop. Such a page keeps its canvas mounted and its connection
|
||||
open while the backend engine stops rendering for it.</li>
|
||||
</ul>
|
||||
<p>The File Explorer page adds a route-leave guard that settles its editor buffer — flushing a pending
|
||||
auto-save, or prompting before discarding manual edits — and can refuse the navigation.</p>
|
||||
<h2 id="the-stores">The Stores</h2>
|
||||
<p>Four Pinia stores are created against the single Pinia instance built at boot. None of them is inside
|
||||
the <code><keep-alive></code>, so a project change resets none of them; only a browser reload rebuilds them.</p>
|
||||
<ul>
|
||||
<li><strong>project</strong> holds <code>projectPath</code>, <code>projectVersion</code>, the admin and project directories, a loading flag
|
||||
and the <code>hasProject</code> computed. Its actions post to the project endpoints and each throws a typed busy
|
||||
error on HTTP 409, which the backend returns when another project file operation is already running —
|
||||
the request is refused rather than queued. The store also owns the subscription to the shared
|
||||
execution-status hub and the watcher that adopts the path that hub broadcasts.</li>
|
||||
<li><strong>appState</strong> holds the debug flag (initialised from whether the page is served from <code>localhost</code>), the
|
||||
physics-options and physics-licensed flags, the language code with the list of codes the server
|
||||
offers, and the Execution division-visibility record. <code>loadServerPreferences</code>, called from the
|
||||
layout's mount hook, hydrates those three groups in independently guarded steps, so a failing
|
||||
endpoint leaves the rest usable. A division-flag write is applied optimistically and rolled back on
|
||||
failure, with a monotonic sequence number so a late response cannot overwrite newer state. Its
|
||||
<code>setMessage</code> is a forwarder into the footer's foreground channel.</li>
|
||||
<li><strong>auth</strong> holds whether the login gate is enabled, whether this session is authenticated, the user
|
||||
name, the version string the login screen shows, and a ready flag set once the first status probe
|
||||
resolves. Every transition re-drives the global hub gate described below.</li>
|
||||
<li><strong>routineProgress</strong> backs the footer's two channels. The foreground channel keeps the latest entry
|
||||
plus a history capped at one hundred entries, which the footer's history button lists; the background
|
||||
channel is a single in-flight job with a message and an optional fraction and keeps no history at
|
||||
all, so it disappears when the job ends. A boot patch mirrors every Quasar toast into the foreground
|
||||
channel, so a toast stays reviewable after it fades.</li>
|
||||
</ul>
|
||||
<h2 id="state-outside-the-stores">State Outside the Stores</h2>
|
||||
<p>A second family of state lives at module scope in composables rather than in a store. The module is
|
||||
evaluated once per page load and its <code>ref</code>s are created there, so every caller of the composable
|
||||
receives the same objects and nothing in a component's lifecycle creates or destroys them.</p>
|
||||
<p>Three of these hold project data and share one lifecycle idiom — <code>useSpindleCapability</code>,
|
||||
<code>useSoftNcRunner</code> and <code>useToolHouse</code>. Each exposes an idempotent <code>ensureInstalled()</code> that, on its first
|
||||
call only, opens a detached effect scope and watches <code>hasProject</code>: the state reloads when a project
|
||||
appears and is cleared when one closes. Every panel that reads the singleton calls <code>ensureInstalled()</code>
|
||||
in its own setup, and every call after the first does nothing.</p>
|
||||
<p>The consequence is the one that matters when reading a panel on screen: <strong>a mounted panel is not
|
||||
refreshed by a change made elsewhere.</strong> A project change unmounts and rebuilds every page, but it does
|
||||
not re-read a singleton — the installer is already installed, and the watch it installed is on a
|
||||
boolean that the load and new actions leave true. What each singleton holds is replaced only by an
|
||||
action on the composable itself, or by a consumer that asks for it explicitly: the Tool House page's
|
||||
mount hook calls the composable's <code>reload()</code>, while the spindle and controller panels call
|
||||
<code>ensureInstalled()</code> alone. The controller branch is the sharpest case. Its leaf panels fetch their own
|
||||
tables on mount and the tree builder re-fetches the runner snapshot it grows children from, but the
|
||||
shared snapshot the panels gate on — the brand, the chain axes, the per-group presence flags and the
|
||||
object key — is replaced only by a brand switch, an Object-Management install, or a close.</p>
|
||||
<p>The remaining module singletons carry no project data and exist to join components that are not in one
|
||||
another's tree: the Execution runtime flags the run page publishes for the nav bar, the sentence cursor
|
||||
shared by the Program file panel and the syntax view, the strip-chart group's reload tick and hovered
|
||||
x label, the two cycle-chart cursor marks the sim and sensor chart groups share, the parked cross-panel
|
||||
line jump, the transport's shared reset flag, and the shared-hub registry with its auth gate.</p>
|
||||
<h2 id="device-local-state">Device-Local State</h2>
|
||||
<p>Three <code>localStorage</code> keys hold state belonging to one browser profile on one machine. None of them is
|
||||
written into the project file and none is sent to the server.</p>
|
||||
<ul>
|
||||
<li>The tree-page view preferences key holds, per tree page, the column-visibility record and the two
|
||||
left-dock row states; and, shared across both pages, the dock pixel widths, the editor row height,
|
||||
the strip/step ratio, the two chart legend widths, the strip x-axis mode, the per-panel resize
|
||||
weights, the Control-Tree expansion list, the last selection per page, the two runner-suit
|
||||
checkboxes, and the three device-local panel switches for the 3D canvas, the CWE canvas and the
|
||||
sentence syntax view. Writes are debounced, and two earlier key names are read once as migration
|
||||
seeds when the current key is absent.</li>
|
||||
<li>The locale key is a paint-time hint only: the boot sequence applies it before mount so the first
|
||||
frame is already translated, then reconciles against the server value, which wins.</li>
|
||||
<li>The File Explorer key holds whether its editor pane is shown, the pane split, the auto-save switch
|
||||
and the sort order.</li>
|
||||
</ul>
|
||||
<p>What is <strong>not</strong> device-local is easy to mistake for it. The physics-options switch, the interface
|
||||
language and the Execution division-visibility flags live in the server's <code>UserConfig</code>, held by a
|
||||
singleton service and written to an XML file in the service's working directory. They are per install,
|
||||
not per browser: two browsers pointed at the same service read and write the same values. The
|
||||
machining project is server-side in the same way — one project is loaded at a time and every connected
|
||||
browser sees it, which is why the status-hub broadcast is what keeps a second tab honest.</p>
|
||||
<p>The URL carries the rest: the route, the <code>?tree=</code> selection on the two Control-Tree pages, the browsed
|
||||
path on the File Explorer route, and the tab segments on the Tool House and Controller routes. Those
|
||||
come back on a reload from the address bar, and when a Control-Tree page is opened with no <code>?tree=</code> the
|
||||
host lands on the stored last selection for that page, falling back to the page's root when the stored
|
||||
id is not in the current project's tree.</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>What</th>
|
||||
<th>Navigation</th>
|
||||
<th>Project change</th>
|
||||
<th>Browser reload</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>A page's own component state, including its Control-Tree host</td>
|
||||
<td>survives</td>
|
||||
<td>rebuilt</td>
|
||||
<td>rebuilt</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>The four Pinia stores</td>
|
||||
<td>survives</td>
|
||||
<td>survives</td>
|
||||
<td>rebuilt</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Module-singleton composables</td>
|
||||
<td>survives</td>
|
||||
<td>survives</td>
|
||||
<td>rebuilt</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>The <code>localStorage</code> preferences</td>
|
||||
<td>survives</td>
|
||||
<td>survives</td>
|
||||
<td>survives</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Route, <code>?tree=</code>, browsed path and tab segments</td>
|
||||
<td>this is what changes</td>
|
||||
<td>survives</td>
|
||||
<td>survives</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Server preferences and the loaded project</td>
|
||||
<td>survives</td>
|
||||
<td>server-side</td>
|
||||
<td>survives</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h2 id="signalr-connections">SignalR Connections</h2>
|
||||
<p>Most hubs are shared singletons built by one factory: the execution-status hub, the CL strip hub, and
|
||||
the four session-message sinks for shell, NC diagnostic, step diagnostic and NC-manipulation
|
||||
diagnostic messages. There is one connection per hub for the whole application, reference-counted by
|
||||
consumer. A component registers as a consumer when it calls the hub's composable and releases on its
|
||||
own unmount; when the count reaches zero the teardown waits out a short grace window, so the
|
||||
remount a project change forces — every consumer dropping and re-adding within the same render flush —
|
||||
keeps its connections rather than renegotiating them.</p>
|
||||
<p>The project store takes out a consumer registration on the execution-status hub when the store is
|
||||
created and never releases it itself, so that hub keeps a consumer no matter which page is showing.</p>
|
||||
<p>A global gate sits in front of all of them. While the optional login gate is enabled and the session is
|
||||
not authenticated — and while auth status is still resolving — hubs stay idle rather than negotiating
|
||||
into a 401. A logout or an intercepted 401 closes every connection; permitting again reconnects the
|
||||
ones a caller had asked for, without the caller asking twice. Reconnection is a dense burst of
|
||||
attempts, then a fixed cadence, then a slow tail that never gives up, and tab visibility or window
|
||||
focus starts a fresh burst immediately.</p>
|
||||
<p>Two kinds of connection are per instance rather than shared:</p>
|
||||
<ul>
|
||||
<li>Each rendering canvas opens its own connection to the rendering hub on mount and stops it on unmount.
|
||||
Because pages are cached, navigating away does not close one, and whether the backend engine stops
|
||||
drawing for it depends on the host. The Execution, General Setup and Tool House pages hand their
|
||||
activation flag to the canvas's <code>active</code> prop, which pauses the engine while the page sits off-screen;
|
||||
the Controller, Machine Tool and Mech Builder canvases and the File Explorer's STL preview bind no
|
||||
such prop, and the Execution page's CWE canvas pins it true, so all of those keep rendering until
|
||||
something unmounts them. Collapsing a panel does close one, unless that panel keeps its content
|
||||
mounted: the Execution page's 3D canvas panel does, so it survives a collapse, while the CWE panel
|
||||
beside it does not and its canvas connection goes with it.</li>
|
||||
<li>The cleanup hub is opened once per Control-Tree host and once each on the Controller and Tool House
|
||||
pages. Its composable also holds the set of IndexService keys that owner registered; on unmount it
|
||||
posts a removal for every one of them and then stops the connection, so a teardown releases the
|
||||
server-side objects the page had indexed even if the hub never connected.</li>
|
||||
</ul>
|
||||
<p>A shared connection therefore closes when its last consumer has been gone longer than the grace window,
|
||||
or when the auth gate shuts. A per-instance connection closes when the component owning it unmounts —
|
||||
which is what a project change does to every page at once, while the shared hubs ride that same remount
|
||||
out inside their grace window.</p>
|
||||
<h2 id="boot-order">Boot Order</h2>
|
||||
<p><code>App.vue</code> renders nothing but the router outlet and holds the wiring that must run exactly once per
|
||||
page load: subscribe the project hub, then fetch project status. Both sit behind a watcher on the auth
|
||||
predicate with a latch rather than behind a mount hook, because auth status may still be resolving at
|
||||
first paint. The router's own guard hydrates auth status before the first navigation and fails open, so
|
||||
a status hiccup cannot lock out an installation that has no login gate. The layout's mount hook then
|
||||
hydrates the server preferences. A successful sign-in navigates with a full page load rather than a
|
||||
router push, so the whole sequence runs again with the authentication cookie present.</p>
|
||||
<h2 id="source-code-path">Source Code Path</h2>
|
||||
<p>See <a class="xref" href="../index.html">HiNC App Anatomy</a> for git repository links.</p>
|
||||
<h3 id="web-application">Web Application</h3>
|
||||
<p>HiNC-2025-webservice (Quasar CLI SPA):</p>
|
||||
<ul>
|
||||
<li><code>wwwroot-src/src/layouts/MainLayout.vue</code> — the project epoch, its two watchers, the keyed
|
||||
<code><keep-alive></code> around the router outlet, the footer, and the server-preference hydration call.</li>
|
||||
<li><code>wwwroot-src/src/App.vue</code> — the auth-gated one-shot wiring: the project hub subscription and the
|
||||
first status fetch.</li>
|
||||
<li><code>wwwroot-src/src/stores/index.ts</code> — the Pinia instance the four stores are created against.</li>
|
||||
<li><code>wwwroot-src/src/stores/project.ts</code> — the project path and version, the directories, the file actions
|
||||
and their busy error, the hub subscription, and the watcher that adopts the broadcast path.</li>
|
||||
<li><code>wwwroot-src/src/stores/appState.ts</code> — the debug and physics flags, the language state, the Execution
|
||||
division config with its optimistic write and sequence guard, and the footer forwarder.</li>
|
||||
<li><code>wwwroot-src/src/stores/auth.ts</code> — the login-gate state and the hub gate it drives.</li>
|
||||
<li><code>wwwroot-src/src/stores/routineProgress.ts</code> — the footer's foreground history and its single live
|
||||
background job.</li>
|
||||
<li><code>wwwroot-src/src/composables/useViewPrefs.ts</code> — the device-local view preferences: the shape, the
|
||||
defaults, the migration seeds and the debounced write.</li>
|
||||
<li><code>wwwroot-src/src/composables/useSoftNcRunner.ts</code> — the controller singleton: the shared runner
|
||||
snapshot, the object key, and the install-once project watch.</li>
|
||||
<li><code>wwwroot-src/src/composables/useSpindleCapability.ts</code> — the spindle singleton on the same lifecycle
|
||||
idiom.</li>
|
||||
<li><code>wwwroot-src/src/composables/useToolHouse.ts</code> — the tool-house singleton and the coalesced reload the
|
||||
page calls on mount.</li>
|
||||
<li><code>wwwroot-src/src/composables/useSharedHub.ts</code> — the shared-hub factory: consumer counting, the
|
||||
teardown grace window, the auth gate, the retry schedule and the focus recovery.</li>
|
||||
<li><code>wwwroot-src/src/composables/useExecutionStatusHub.ts</code> — the status, cursor and message payloads the
|
||||
store and the footer read.</li>
|
||||
<li><code>wwwroot-src/src/composables/useClStripHub.ts</code> — the strip snapshot and update counter the charts
|
||||
watch.</li>
|
||||
<li><code>wwwroot-src/src/composables/useSessionSinkHub.ts</code> — the four message sinks and their
|
||||
notify-and-re-pull contract.</li>
|
||||
<li><code>wwwroot-src/src/composables/useCleanupHub.ts</code> — the per-instance cleanup connection and the key set
|
||||
it releases on unmount.</li>
|
||||
<li><code>wwwroot-src/src/composables/useExecutionTransport.ts</code> — the activation-scoped keyboard shortcuts and
|
||||
the shared reset flag.</li>
|
||||
<li><code>wwwroot-src/src/composables/useExecutionRuntime.ts</code> — the runtime flags the run page publishes.</li>
|
||||
<li><code>wwwroot-src/src/composables/useSentenceCursor.ts</code> — the shared source cursor and its install-once
|
||||
watch on step selection.</li>
|
||||
<li><code>wwwroot-src/src/composables/useStripChartGroup.ts</code> — the group reload tick and the hovered x label.</li>
|
||||
<li><code>wwwroot-src/src/composables/useCycleSyncMark.ts</code> — the per-group cycle-chart cursor mark the sim
|
||||
and sensor charts share.</li>
|
||||
<li><code>wwwroot-src/src/composables/useConversionJump.ts</code> — the parked cross-panel jump.</li>
|
||||
<li><code>wwwroot-src/src/components/RenderingCanvas.vue</code> — the per-instance rendering connection, its mount
|
||||
and unmount lifecycle, and the mounted guard that survives a mid-await teardown.</li>
|
||||
<li><code>wwwroot-src/src/components/panels/PanelExpansion.vue</code> — the expansion row, and the keep-mounted flag
|
||||
that decides whether a collapse unmounts its content.</li>
|
||||
<li><code>wwwroot-src/src/components/AppFooter.vue</code> — the two footer channels and the recent-message list.</li>
|
||||
<li><code>wwwroot-src/src/components/FileExplorer.vue</code> — the explorer's own device-local preference key.</li>
|
||||
<li><code>wwwroot-src/src/components/controlTree/useControlTreeHost.ts</code> — the per-page host: the route-name
|
||||
guard on the <code>?tree=</code> sync, the landing selection, and the cleanup registrations.</li>
|
||||
<li><code>wwwroot-src/src/pages/ExecutionPage.vue</code> — the activation flag, the once-per-project initialization,
|
||||
and the panel that keeps the 3D canvas mounted through a collapse.</li>
|
||||
<li><code>wwwroot-src/src/pages/GeneralSetupPage.vue</code> — the same lifecycle for the equipment host.</li>
|
||||
<li><code>wwwroot-src/src/pages/ToolHousePage.vue</code> — the page that reloads its singleton explicitly on mount.</li>
|
||||
<li><code>wwwroot-src/src/pages/ControllerPage.vue</code>, <code>wwwroot-src/src/pages/MachineToolPage.vue</code>,
|
||||
<code>wwwroot-src/src/pages/MechBuilderPage.vue</code> and <code>wwwroot-src/src/components/StlPreviewPane.vue</code> —
|
||||
the canvases mounted with no <code>active</code> binding.</li>
|
||||
<li><code>wwwroot-src/src/components/execution/StepVolumePanel.vue</code> — the CWE canvas that pins <code>active</code> true
|
||||
and is stopped only by its own unmount.</li>
|
||||
<li><code>wwwroot-src/src/pages/FileExplorerPage.vue</code> — the route-leave guard that settles the editor buffer.</li>
|
||||
<li><code>wwwroot-src/src/pages/LoginPage.vue</code> — the full-page navigation after a successful sign-in.</li>
|
||||
<li><code>wwwroot-src/src/router/index.ts</code> — the auth guard that hydrates status before the first navigation.</li>
|
||||
<li><code>wwwroot-src/src/router/routes.ts</code> — which routes render inside the layout and which do not.</li>
|
||||
<li><code>wwwroot-src/src/boot/auth.ts</code> — the fetch wrapper that turns a 401 into a logged-out store and a
|
||||
bounce to the login screen.</li>
|
||||
<li><code>wwwroot-src/src/boot/i18n.ts</code> — the cached-locale fast path and the server reconcile.</li>
|
||||
<li><code>wwwroot-src/src/boot/routine-toast.ts</code> — the toast mirror into the footer channel.</li>
|
||||
<li><code>wwwroot-src/src/i18n/index.ts</code> — the locale storage key and the single place a locale change is
|
||||
applied.</li>
|
||||
<li><code>wwwroot-src/src/api/preference.ts</code> — the typed wrappers over the preference endpoints the app-state
|
||||
store hydrates from.</li>
|
||||
<li><code>Environments/ProjectController.cs</code> — the status, new, load, save, save-as, reload and close
|
||||
endpoints, and the conflict reply that becomes the client's busy error.</li>
|
||||
<li><code>Environments/PreferenceController.cs</code> — the endpoints behind the server-held preferences.</li>
|
||||
<li><code>Environments/UserConfig.cs</code> — the persisted user configuration: the physics switch, the language
|
||||
code, the graphic-cache limits, the step-present list and the Execution division config.</li>
|
||||
<li><code>Environments/UserService.cs</code> — the singleton that owns that configuration and writes it to file.</li>
|
||||
<li><code>Execution/ExecutionStatusService.cs</code> — the broadcast that carries a project change to every
|
||||
connected browser.</li>
|
||||
<li><code>Program.cs</code> — where the user-configuration service is registered and its file path fixed.</li>
|
||||
</ul>
|
||||
<h2 id="see-also">See Also</h2>
|
||||
<ul>
|
||||
<li><a class="xref" href="control-tree.html">Control Tree</a> — the per-page host this epoch destroys and rebuilds, and the selection it
|
||||
restores from device-local storage</li>
|
||||
<li><a class="xref" href="program-and-hosting.html">Program and Hosting</a> — how the SPA is served and hosted, and where the server-side
|
||||
singletons this page reads actually live</li>
|
||||
<li><a class="xref" href="../shell/main-panel.html">Main Panel</a> — the shell around the router outlet: the menu bar that fires the project
|
||||
actions and the footer that shows their outcome</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||
<div class="contribution d-print-none">
|
||||
</div>
|
||||
|
||||
<div class="next-article d-print-none border-top" id="nextArticle"></div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="affix">
|
||||
<nav id="affix"></nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div class="container-xxl search-results" id="search-results"></div>
|
||||
|
||||
<footer class="border-top text-secondary">
|
||||
<div class="container-xxl">
|
||||
<div class="flex-fill">
|
||||
<span> Copyright © 2025 <a href='https://superhightech.com.tw'>Tech Coordinate</a>. All rights reserved. <a href='https://superhightech.com.tw'>超級高科技股份有限公司</a> © 2025 版權所有 </span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user