Перейти к содержимому

SvelteKit

Это содержимое пока не доступно на вашем языке.

XenolithGraph ships a Svelte adapter (@xenolithengine/graph-svelte) and a framework-agnostic Web Component (@xenolithengine/graph-wc). Both run only in the browser, so SvelteKit needs to be told to skip them on the server.

Install

Terminal window
pnpm add @xenolithengine/graph-editor @xenolithengine/graph-svelte pixi.js
# or, for the framework-agnostic web-component path:
pnpm add @xenolithengine/graph-editor @xenolithengine/graph-wc pixi.js

pixi.js is a peer dependency.

src/routes/editor/+page.svelte
<script lang="ts">
import { browser } from '$app/environment'
import { onMount } from 'svelte'
let Editor: any = null
onMount(async () => {
if (browser) Editor = (await import('$lib/Editor.svelte')).default
})
</script>
{#if Editor}
<svelte:component this={Editor} />
{:else}
<div style="height:100vh;background:#121212;"></div>
{/if}
src/lib/Editor.svelte
<script lang="ts">
import { xenolith } from '@xenolithengine/graph-svelte'
import { myGraph } from '$lib/data'
const onNodeClick = (e: CustomEvent) => console.log('clicked', e.detail.nodeId)
</script>
<div
use:xenolith={{ graph: myGraph, fitOnLoad: true, minimap: true }}
on:node-click={onNodeClick}
style="height:100vh"
></div>

The Svelte adapter is an action (use:xenolith={props}) rather than a component. Pass the graph + options as props; the action re-dispatches every editor event off the host element as a kebab-named CustomEvent (node-click, edge-connected, selection-changed, …). For imperative setup that needs the editor instance (registering schemas, custom plugins), use pattern 2 (Web Component) and listen for its ready event.

Pattern 2 — Web Component (framework-neutral)

src/routes/editor/+page.svelte
<script lang="ts">
import { browser } from '$app/environment'
import { onMount } from 'svelte'
import { myGraph } from '$lib/data'
let el: HTMLElement
onMount(async () => {
if (!browser) return
const { register } = await import('@xenolithengine/graph-wc')
register() // defines <xenolith-graph>
// The WC takes `graph` via the JS property — set it after the element is in the DOM and the
// editor mounts itself + loads it. For imperative work (registering schemas, plugins) poll
// `el.editor` until it's non-null.
;(el as any).graph = myGraph
;(el as any).setAttribute('fit-on-load', '')
})
</script>
<xenolith-graph bind:this={el} class="xeno" minimap style="display:block;height:100vh"></xenolith-graph>

Disable SSR for editor routes

If a route ONLY renders the editor:

src/routes/editor/+page.ts
export const ssr = false

Use this when the route’s only purpose is the editor — keep SSR enabled for content-heavy routes.

Why no SSR mode

The renderer needs WebGL + a real <canvas>. There’s no static-HTML output mode. If you need a server-rendered preview of a graph (a thumbnail in a list, an OG card), call editor.exportImage() on the client and upload the PNG.

Vite config — dedupe PIXI

If you import PIXI from multiple places, keep a single physical copy:

vite.config.ts
export default defineConfig({
resolve: { dedupe: ['pixi.js'] },
optimizeDeps: { include: ['pixi.js'] },
})

PIXI’s extension registry throws “Extension type X already has a handler” if you load it twice — same trap we hit in our own monorepo.