Split apart the frontend Editor type into SubscriptionsRouter and EditorHandle (#3923)

* Remove the unused Editor.raw/wasmMemory/wasmImport

* Split out Editor.subscriptions

* Replace editor.handle.* with editor.* (1 of 2)

* Replace editor.handle.* with editor.* (2 of 2)

* Replace Editor typedef with EditorHandle import

* Pluralize subscription-router and rename subscriptionsRef->subscriptionsRouter and editorRef->editorHandle

* Remove editor.ts

* Update the readme

* Fix demo art loading bug
This commit is contained in:
Keavon Chambers
2026-03-20 23:34:13 -07:00
committed by GitHub
parent 64fd12a1a0
commit ed7987c881
40 changed files with 549 additions and 584 deletions

View File

@@ -1,7 +1,7 @@
<script lang="ts">
import { getContext, tick } from "svelte";
import type { Editor } from "@graphite/editor";
import type { EditorHandle } from "@graphite/../wasm/pkg/graphite_wasm";
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
@@ -25,7 +25,7 @@
const BUTTON_LEFT = 0;
const BUTTON_MIDDLE = 1;
const editor = getContext<Editor>("editor");
const editor = getContext<EditorHandle>("editor");
export let tabMinWidths = false;
export let tabCloseButtons = false;
@@ -56,7 +56,7 @@
}
</script>
<LayoutCol on:pointerdown={() => panelType && editor.handle.setActivePanel(panelType)} class={`panel ${className}`.trim()} {classes} style={styleName} {styles}>
<LayoutCol on:pointerdown={() => panelType && editor.setActivePanel(panelType)} class={`panel ${className}`.trim()} {classes} style={styleName} {styles}>
<LayoutRow class="tab-bar" classes={{ "min-widths": tabMinWidths }}>
<LayoutRow class="tab-group" scrollableX={true} on:click={onEmptySpaceAction} on:auxclick={onEmptySpaceAction}>
{#each tabLabels as tabLabel, tabIndex}

View File

@@ -2,32 +2,33 @@
import { getContext, onMount, onDestroy } from "svelte";
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
import type { Editor } from "@graphite/editor";
import type { SubscriptionsRouter } from "/src/subscriptions-router";
import { patchLayout } from "@graphite/utility-functions/widgets";
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
import Separator from "@graphite/components/widgets/labels/Separator.svelte";
import WidgetLayout from "@graphite/components/widgets/WidgetLayout.svelte";
const editor = getContext<Editor>("editor");
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
let statusBarHintsLayout: Layout = [];
let statusBarInfoLayout: Layout = [];
onMount(() => {
editor.subscriptions.subscribeLayoutUpdate("StatusBarHints", (data) => {
subscriptions.subscribeLayoutUpdate("StatusBarHints", (data) => {
patchLayout(statusBarHintsLayout, data);
statusBarHintsLayout = statusBarHintsLayout;
});
editor.subscriptions.subscribeLayoutUpdate("StatusBarInfo", (data) => {
subscriptions.subscribeLayoutUpdate("StatusBarInfo", (data) => {
patchLayout(statusBarInfoLayout, data);
statusBarInfoLayout = statusBarInfoLayout;
});
});
onDestroy(() => {
editor.subscriptions.unsubscribeLayoutUpdate("StatusBarHints");
editor.subscriptions.unsubscribeLayoutUpdate("StatusBarInfo");
subscriptions.unsubscribeLayoutUpdate("StatusBarHints");
subscriptions.unsubscribeLayoutUpdate("StatusBarInfo");
});
</script>

View File

@@ -2,12 +2,12 @@
import { getContext, onMount, onDestroy } from "svelte";
import { isPlatformNative } from "@graphite/../wasm/pkg/graphite_wasm";
import type { Layout } from "@graphite/../wasm/pkg/graphite_wasm";
import type { Editor } from "@graphite/editor";
import type { EditorHandle, Layout } from "@graphite/../wasm/pkg/graphite_wasm";
import type { AppWindowStore } from "@graphite/stores/app-window";
import { enterFullscreen, exitFullscreen } from "@graphite/stores/fullscreen";
import type { FullscreenStore } from "@graphite/stores/fullscreen";
import type { TooltipStore } from "@graphite/stores/tooltip";
import type { SubscriptionsRouter } from "/src/subscriptions-router";
import { patchLayout } from "@graphite/utility-functions/widgets";
import LayoutRow from "@graphite/components/layout/LayoutRow.svelte";
@@ -16,8 +16,9 @@
const keyboardLockApiSupported = navigator.keyboard !== undefined && "lock" in navigator.keyboard;
const editor = getContext<EditorHandle>("editor");
const subscriptions = getContext<SubscriptionsRouter>("subscriptions");
const appWindow = getContext<AppWindowStore>("appWindow");
const editor = getContext<Editor>("editor");
const fullscreen = getContext<FullscreenStore>("fullscreen");
const tooltip = getContext<TooltipStore>("tooltip");
@@ -29,14 +30,14 @@
$: height = $appWindow.platform === "Mac" ? 28 * (1 / $appWindow.uiScale) : 28;
onMount(() => {
editor.subscriptions.subscribeLayoutUpdate("MenuBar", (data) => {
subscriptions.subscribeLayoutUpdate("MenuBar", (data) => {
patchLayout(menuBarLayout, data);
menuBarLayout = menuBarLayout;
});
});
onDestroy(() => {
editor.subscriptions.unsubscribeLayoutUpdate("MenuBar");
subscriptions.unsubscribeLayoutUpdate("MenuBar");
});
</script>
@@ -48,7 +49,7 @@
{/if}
</LayoutRow>
<!-- Window frame -->
<LayoutRow class="window-frame" on:mousedown={() => !isFullscreen && editor.handle.appWindowDrag()} on:dblclick={() => !isFullscreen && editor.handle.appWindowMaximize()} />
<LayoutRow class="window-frame" on:mousedown={() => !isFullscreen && editor.appWindowDrag()} on:dblclick={() => !isFullscreen && editor.appWindowMaximize()} />
<!-- Window buttons -->
<LayoutRow class="window-buttons" classes={{ fullscreen: showFullscreenButton, windows: $appWindow.platform === "Windows", linux: $appWindow.platform === "Linux" }}>
{#if $appWindow.platform !== "Mac"}
@@ -60,20 +61,20 @@
: undefined}
tooltipShortcut={$tooltip.fullscreenShortcut}
on:click={() => {
if (isPlatformNative()) editor.handle.appWindowFullscreen();
if (isPlatformNative()) editor.appWindowFullscreen();
else ($fullscreen.windowFullscreen ? exitFullscreen : enterFullscreen)();
}}
>
<IconLabel icon={isFullscreen ? "FullscreenExit" : "FullscreenEnter"} />
</LayoutRow>
{:else}
<LayoutRow tooltipLabel="Minimize" on:click={() => editor.handle.appWindowMinimize()}>
<LayoutRow tooltipLabel="Minimize" on:click={() => editor.appWindowMinimize()}>
<IconLabel icon="WindowButtonWinMinimize" />
</LayoutRow>
<LayoutRow tooltipLabel={$appWindow.maximized ? ($appWindow.platform === "Windows" ? "Restore Down" : "Unmaximize") : "Maximize"} on:click={() => editor.handle.appWindowMaximize()}>
<LayoutRow tooltipLabel={$appWindow.maximized ? ($appWindow.platform === "Windows" ? "Restore Down" : "Unmaximize") : "Maximize"} on:click={() => editor.appWindowMaximize()}>
<IconLabel icon={$appWindow.maximized ? "WindowButtonWinRestoreDown" : "WindowButtonWinMaximize"} />
</LayoutRow>
<LayoutRow tooltipLabel="Close" on:click={() => editor.handle.appWindowClose()}>
<LayoutRow tooltipLabel="Close" on:click={() => editor.appWindowClose()}>
<IconLabel icon="WindowButtonWinClose" />
</LayoutRow>
{/if}

View File

@@ -1,8 +1,7 @@
<script lang="ts">
import { getContext, onDestroy } from "svelte";
import type { OpenDocument } from "@graphite/../wasm/pkg/graphite_wasm";
import type { Editor } from "@graphite/editor";
import type { EditorHandle, OpenDocument } from "@graphite/../wasm/pkg/graphite_wasm";
import type { PortfolioStore } from "@graphite/stores/portfolio";
import LayoutCol from "@graphite/components/layout/LayoutCol.svelte";
@@ -35,13 +34,13 @@
$: documentTabLabels = $portfolio.documents.map((doc: OpenDocument) => {
const name = doc.details.name;
const unsaved = !doc.details.isSaved;
if (!editor.handle.inDevelopmentMode()) return { name, unsaved };
if (!editor.inDevelopmentMode()) return { name, unsaved };
const tooltipDescription = `Document ID: ${doc.id}`;
return { name, unsaved, tooltipLabel: name, tooltipDescription };
});
const editor = getContext<Editor>("editor");
const editor = getContext<EditorHandle>("editor");
const portfolio = getContext<PortfolioStore>("portfolio");
function resizePanel(e: PointerEvent) {
@@ -151,9 +150,9 @@
tabCloseButtons={true}
tabMinWidths={true}
tabLabels={documentTabLabels}
emptySpaceAction={() => editor.handle.newDocumentDialog()}
clickAction={(tabIndex) => editor.handle.selectDocument($portfolio.documents[tabIndex].id)}
closeAction={(tabIndex) => editor.handle.closeDocumentWithConfirmation($portfolio.documents[tabIndex].id)}
emptySpaceAction={() => editor.newDocumentDialog()}
clickAction={(tabIndex) => editor.selectDocument($portfolio.documents[tabIndex].id)}
closeAction={(tabIndex) => editor.closeDocumentWithConfirmation($portfolio.documents[tabIndex].id)}
tabActiveIndex={$portfolio.activeDocumentIndex}
bind:this={documentPanel}
/>