mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-05-22 21:38:52 +00:00
Compare commits
3 Commits
perf/test-
...
litegraph/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fd5a94e072 | ||
|
|
ad63f7cb9b | ||
|
|
f7ef563b46 |
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"last_node_id": 1,
|
||||
"last_link_id": 0,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "LoadImage",
|
||||
"pos": [50, 120],
|
||||
"size": [400, 200],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": null
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": [
|
||||
"147257c95a3e957e0deee73a077cfec89da2d906dd086ca70a2b0c897a9591d6e.png[output]",
|
||||
"image"
|
||||
]
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {
|
||||
"ds": {
|
||||
"offset": [0, 0],
|
||||
"scale": 1
|
||||
}
|
||||
},
|
||||
"version": 0.4
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
{
|
||||
"last_node_id": 3,
|
||||
"last_link_id": 0,
|
||||
"nodes": [
|
||||
{
|
||||
"id": 1,
|
||||
"type": "LoadImage",
|
||||
"pos": [50, 120],
|
||||
"size": [400, 200],
|
||||
"flags": {},
|
||||
"order": 0,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "IMAGE",
|
||||
"type": "IMAGE",
|
||||
"links": null
|
||||
},
|
||||
{
|
||||
"name": "MASK",
|
||||
"type": "MASK",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadImage"
|
||||
},
|
||||
"widgets_values": ["ComfyUI_00001_.png [output]", "image"]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"type": "LoadVideo",
|
||||
"pos": [430, 120],
|
||||
"size": [400, 200],
|
||||
"flags": {},
|
||||
"order": 1,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "VIDEO",
|
||||
"type": "VIDEO",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadVideo"
|
||||
},
|
||||
"widgets_values": ["clip.mp4 [output]", "image"]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"type": "LoadAudio",
|
||||
"pos": [810, 120],
|
||||
"size": [400, 200],
|
||||
"flags": {},
|
||||
"order": 2,
|
||||
"mode": 0,
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"name": "AUDIO",
|
||||
"type": "AUDIO",
|
||||
"links": null
|
||||
}
|
||||
],
|
||||
"properties": {
|
||||
"Node name for S&R": "LoadAudio"
|
||||
},
|
||||
"widgets_values": ["sound.wav [output]", null, ""]
|
||||
}
|
||||
],
|
||||
"links": [],
|
||||
"groups": [],
|
||||
"config": {},
|
||||
"extra": {
|
||||
"ds": {
|
||||
"offset": [0, 0],
|
||||
"scale": 1
|
||||
}
|
||||
},
|
||||
"version": 0.4
|
||||
}
|
||||
BIN
browser_tests/assets/plain_video.mp4
Normal file
BIN
browser_tests/assets/plain_video.mp4
Normal file
Binary file not shown.
@@ -390,58 +390,6 @@ test.describe('Performance', { tag: ['@perf'] }, () => {
|
||||
}
|
||||
)
|
||||
|
||||
test('fast pan memory pressure', async ({ comfyPage }) => {
|
||||
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
|
||||
await comfyPage.workflow.loadWorkflow('large-graph-workflow')
|
||||
await comfyPage.vueNodes.waitForNodes()
|
||||
|
||||
const canvas = comfyPage.canvas
|
||||
const box = await canvas.boundingBox()
|
||||
if (!box) throw new Error('Canvas bounding box not available')
|
||||
|
||||
await comfyPage.perf.startMeasuring()
|
||||
|
||||
// Rapidly pan back and forth across the large graph (245 nodes).
|
||||
// Each pan pass triggers reactive node instrumentation as nodes
|
||||
// enter/leave the viewport. Without idempotent instrumentation,
|
||||
// each pass leaks ComputedRefImpl, Link, Dep, and EventListener
|
||||
// objects (~198K ComputedRefImpl and 1.5M Link objects observed
|
||||
// in the original heap snapshot analysis).
|
||||
const centerX = box.x + box.width / 2
|
||||
const centerY = box.y + box.height / 2
|
||||
|
||||
for (let pass = 0; pass < 5; pass++) {
|
||||
await comfyPage.page.mouse.move(centerX, centerY)
|
||||
await comfyPage.page.mouse.down({ button: 'middle' })
|
||||
for (let i = 0; i < 60; i++) {
|
||||
await comfyPage.page.mouse.move(
|
||||
centerX + i * 8,
|
||||
centerY + (i % 2 === 0 ? i * 3 : -i * 3)
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
await comfyPage.page.mouse.up({ button: 'middle' })
|
||||
|
||||
// Return to center for next pass
|
||||
await comfyPage.page.mouse.move(centerX, centerY)
|
||||
await comfyPage.page.mouse.down({ button: 'middle' })
|
||||
for (let i = 0; i < 60; i++) {
|
||||
await comfyPage.page.mouse.move(
|
||||
centerX - i * 8,
|
||||
centerY - (i % 2 === 0 ? i * 3 : -i * 3)
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
await comfyPage.page.mouse.up({ button: 'middle' })
|
||||
}
|
||||
|
||||
const m = await comfyPage.perf.stopMeasuring('fast-pan-memory')
|
||||
recordMeasurement(m)
|
||||
console.log(
|
||||
`Fast pan memory: ${(m.heapDeltaBytes / 1024 / 1024).toFixed(1)}MB heap delta, ${m.eventListeners} event listeners, ${m.taskDurationMs.toFixed(1)}ms task`
|
||||
)
|
||||
})
|
||||
|
||||
test('workflow execution', async ({ comfyPage }) => {
|
||||
// Uses lightweight PrimitiveString → PreviewAny workflow (no GPU needed)
|
||||
await comfyPage.workflow.loadWorkflow('execution/partial_execution')
|
||||
|
||||
@@ -0,0 +1,357 @@
|
||||
import { expect, mergeTests } from '@playwright/test'
|
||||
import type { Page, Route } from '@playwright/test'
|
||||
import type { Asset, ListAssetsResponse } from '@comfyorg/ingest-types'
|
||||
|
||||
import {
|
||||
assetRequestIncludesTag,
|
||||
createCloudAssetsFixture
|
||||
} from '@e2e/fixtures/assetApiFixture'
|
||||
import { comfyPageFixture } from '@e2e/fixtures/ComfyPage'
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
import { jobsApiMockFixture } from '@e2e/fixtures/jobsApiMockFixture'
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
import {
|
||||
createMockJob,
|
||||
createMockJobRecords
|
||||
} from '@e2e/fixtures/utils/jobFixtures'
|
||||
import { PropertiesPanelHelper } from '@e2e/tests/propertiesPanel/PropertiesPanelHelper'
|
||||
|
||||
const ossTest = mergeTests(comfyPageFixture, jobsApiMockFixture)
|
||||
const outputHash =
|
||||
'147257c95a3e957e0deee73a077cfec89da2d906dd086ca70a2b0c897a9591d6e.png'
|
||||
const plainVideoFileName = 'plain_video.mp4'
|
||||
const graphDropPosition = { x: 500, y: 300 }
|
||||
const missingMediaUploadObservationMs = 1_000
|
||||
const missingMediaUploadPollMs = 100
|
||||
|
||||
const cloudOutputAsset: Asset = {
|
||||
id: 'test-output-hash-001',
|
||||
name: 'ComfyUI_00001_.png',
|
||||
asset_hash: outputHash,
|
||||
size: 4_194_304,
|
||||
mime_type: 'image/png',
|
||||
tags: ['output'],
|
||||
created_at: '2026-05-01T00:00:00Z',
|
||||
updated_at: '2026-05-01T00:00:00Z',
|
||||
last_access_time: '2026-05-01T00:00:00Z'
|
||||
}
|
||||
|
||||
const cloudUploadedVideoAsset: Asset = {
|
||||
id: 'test-uploaded-video-001',
|
||||
name: plainVideoFileName,
|
||||
asset_hash: plainVideoFileName,
|
||||
size: 1_024,
|
||||
mime_type: 'video/mp4',
|
||||
tags: ['input'],
|
||||
created_at: '2026-05-01T00:00:00Z',
|
||||
updated_at: '2026-05-01T00:00:00Z',
|
||||
last_access_time: '2026-05-01T00:00:00Z'
|
||||
}
|
||||
|
||||
// The Cloud test app starts with a default LoadImage node. Keep that baseline
|
||||
// input resolvable so this spec only observes the media it creates.
|
||||
const cloudDefaultGraphInputAsset: Asset = {
|
||||
id: 'test-default-input-001',
|
||||
name: '00000000000000000000000Aexample.png',
|
||||
asset_hash: '00000000000000000000000Aexample.png',
|
||||
size: 1_024,
|
||||
mime_type: 'image/png',
|
||||
tags: ['input'],
|
||||
created_at: '2026-05-01T00:00:00Z',
|
||||
updated_at: '2026-05-01T00:00:00Z',
|
||||
last_access_time: '2026-05-01T00:00:00Z'
|
||||
}
|
||||
|
||||
interface CloudUploadAssetState {
|
||||
isUploadedAssetAvailable: boolean
|
||||
}
|
||||
|
||||
const cloudOutputTest = createCloudAssetsFixture([cloudOutputAsset])
|
||||
const cloudUploadAssetStateByPage = new WeakMap<Page, CloudUploadAssetState>()
|
||||
const cloudUploadRaceTest = comfyPageFixture.extend<{
|
||||
markUploadedCloudAssetAvailable: () => void
|
||||
}>({
|
||||
page: async ({ page }, use) => {
|
||||
const state: CloudUploadAssetState = {
|
||||
isUploadedAssetAvailable: false
|
||||
}
|
||||
cloudUploadAssetStateByPage.set(page, state)
|
||||
|
||||
const assetsRouteHandler = async (route: Route) => {
|
||||
const allAssets = [
|
||||
cloudDefaultGraphInputAsset,
|
||||
...(state.isUploadedAssetAvailable ? [cloudUploadedVideoAsset] : [])
|
||||
]
|
||||
const includeTags =
|
||||
new URL(route.request().url()).searchParams
|
||||
.get('include_tags')
|
||||
?.split(',')
|
||||
.filter(Boolean) ?? []
|
||||
const assets = includeTags.length
|
||||
? allAssets.filter((asset) =>
|
||||
asset.tags?.some((tag) => includeTags.includes(tag))
|
||||
)
|
||||
: allAssets
|
||||
const response: ListAssetsResponse = {
|
||||
assets,
|
||||
total: assets.length,
|
||||
has_more: false
|
||||
}
|
||||
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: 'application/json',
|
||||
body: JSON.stringify(response)
|
||||
})
|
||||
}
|
||||
|
||||
await page.route(/\/api\/assets(?:\?.*)?$/, assetsRouteHandler)
|
||||
await use(page)
|
||||
await page.unroute(/\/api\/assets(?:\?.*)?$/, assetsRouteHandler)
|
||||
cloudUploadAssetStateByPage.delete(page)
|
||||
},
|
||||
markUploadedCloudAssetAvailable: async ({ page }, use) => {
|
||||
await use(() => {
|
||||
const state = cloudUploadAssetStateByPage.get(page)
|
||||
if (state) state.isUploadedAssetAvailable = true
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
async function enableErrorsTab(comfyPage: ComfyPage) {
|
||||
await comfyPage.settings.setSetting(
|
||||
'Comfy.RightSidePanel.ShowErrorsTab',
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
function getErrorOverlay(comfyPage: ComfyPage) {
|
||||
return comfyPage.page.getByTestId(TestIds.dialogs.errorOverlay)
|
||||
}
|
||||
|
||||
async function expectNoErrorsTab(comfyPage: ComfyPage) {
|
||||
await expect(getErrorOverlay(comfyPage)).toBeHidden()
|
||||
|
||||
const panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await panel.open(comfyPage.actionbar.propertiesButton)
|
||||
await expect(
|
||||
panel.root.getByTestId(TestIds.propertiesPanel.errorsTab)
|
||||
).toBeHidden()
|
||||
}
|
||||
|
||||
async function delayNextUpload(comfyPage: ComfyPage) {
|
||||
let releaseUpload!: () => void
|
||||
let resolveUploadStarted!: () => void
|
||||
const uploadStarted = new Promise<void>((resolve) => {
|
||||
resolveUploadStarted = resolve
|
||||
})
|
||||
const release = new Promise<void>((resolve) => {
|
||||
releaseUpload = resolve
|
||||
})
|
||||
|
||||
const uploadRouteHandler = async (route: Route) => {
|
||||
resolveUploadStarted()
|
||||
await release
|
||||
await route.continue()
|
||||
}
|
||||
|
||||
await comfyPage.page.route('**/upload/image', uploadRouteHandler)
|
||||
|
||||
return {
|
||||
waitForUploadStarted: () => uploadStarted,
|
||||
finishUpload: async () => {
|
||||
const uploadResponse = comfyPage.page.waitForResponse(
|
||||
(response) =>
|
||||
response.url().includes('/upload/image') && response.status() === 200,
|
||||
{ timeout: 10_000 }
|
||||
)
|
||||
releaseUpload()
|
||||
try {
|
||||
await uploadResponse
|
||||
} finally {
|
||||
await comfyPage.page.unroute('**/upload/image', uploadRouteHandler)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function expectLoadVideoUploading(comfyPage: ComfyPage) {
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate(() =>
|
||||
window.app!.graph.nodes.some(
|
||||
(node) => node.type === 'LoadVideo' && node.isUploading
|
||||
)
|
||||
),
|
||||
{ timeout: 5_000 }
|
||||
)
|
||||
.toBe(true)
|
||||
}
|
||||
|
||||
async function expectNoMissingMediaDuringUpload(comfyPage: ComfyPage) {
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
let sawErrorOverlay = false
|
||||
const startedAt = Date.now()
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
sawErrorOverlay =
|
||||
sawErrorOverlay || (await getErrorOverlay(comfyPage).isVisible())
|
||||
return (
|
||||
!sawErrorOverlay &&
|
||||
Date.now() - startedAt >= missingMediaUploadObservationMs
|
||||
)
|
||||
},
|
||||
{
|
||||
timeout: missingMediaUploadObservationMs + missingMediaUploadPollMs * 5,
|
||||
intervals: [missingMediaUploadPollMs]
|
||||
}
|
||||
)
|
||||
.toBe(true)
|
||||
}
|
||||
|
||||
function outputHistoryJobs() {
|
||||
return createMockJobRecords([
|
||||
createMockJob({
|
||||
id: 'history-output-image',
|
||||
preview_output: {
|
||||
filename: 'ComfyUI_00001_.png',
|
||||
subfolder: '',
|
||||
type: 'output',
|
||||
nodeId: '1',
|
||||
mediaType: 'images'
|
||||
}
|
||||
}),
|
||||
createMockJob({
|
||||
id: 'history-output-video',
|
||||
preview_output: {
|
||||
filename: 'clip.mp4',
|
||||
subfolder: '',
|
||||
type: 'output',
|
||||
nodeId: '2',
|
||||
mediaType: 'video'
|
||||
}
|
||||
}),
|
||||
createMockJob({
|
||||
id: 'history-output-audio',
|
||||
preview_output: {
|
||||
filename: 'sound.wav',
|
||||
subfolder: '',
|
||||
type: 'output',
|
||||
nodeId: '3',
|
||||
mediaType: 'audio'
|
||||
}
|
||||
})
|
||||
])
|
||||
}
|
||||
|
||||
ossTest.describe(
|
||||
'Errors tab - OSS missing media runtime sources',
|
||||
{ tag: '@ui' },
|
||||
() => {
|
||||
ossTest.beforeEach(async ({ comfyPage }) => {
|
||||
await enableErrorsTab(comfyPage)
|
||||
})
|
||||
|
||||
ossTest(
|
||||
'resolves annotated output media from job history',
|
||||
async ({ comfyPage, jobsApi }) => {
|
||||
await jobsApi.mockJobs(outputHistoryJobs())
|
||||
|
||||
await comfyPage.workflow.loadWorkflow(
|
||||
'missing/missing_media_output_annotations'
|
||||
)
|
||||
|
||||
await expectNoErrorsTab(comfyPage)
|
||||
}
|
||||
)
|
||||
|
||||
ossTest(
|
||||
'does not surface missing media while dropped video upload is in progress',
|
||||
async ({ comfyFiles, comfyPage }) => {
|
||||
await comfyPage.nodeOps.clearGraph()
|
||||
const delayedUpload = await delayNextUpload(comfyPage)
|
||||
|
||||
await comfyPage.dragDrop.dragAndDropFile(plainVideoFileName, {
|
||||
dropPosition: graphDropPosition
|
||||
})
|
||||
await delayedUpload.waitForUploadStarted()
|
||||
comfyFiles.deleteAfterTest({
|
||||
filename: plainVideoFileName,
|
||||
type: 'input'
|
||||
})
|
||||
|
||||
await expectLoadVideoUploading(comfyPage)
|
||||
await expectNoMissingMediaDuringUpload(comfyPage)
|
||||
|
||||
await delayedUpload.finishUpload()
|
||||
await expect(getErrorOverlay(comfyPage)).toBeHidden()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
cloudOutputTest.describe(
|
||||
'Errors tab - Cloud missing media runtime sources',
|
||||
{ tag: '@cloud' },
|
||||
() => {
|
||||
cloudOutputTest.beforeEach(async ({ comfyPage }) => {
|
||||
await enableErrorsTab(comfyPage)
|
||||
})
|
||||
|
||||
cloudOutputTest(
|
||||
'resolves compact annotated output media from output assets',
|
||||
async ({ cloudAssetRequests, comfyPage }) => {
|
||||
await comfyPage.workflow.loadWorkflow(
|
||||
'missing/missing_media_cloud_output_annotation'
|
||||
)
|
||||
|
||||
await expect
|
||||
.poll(() =>
|
||||
cloudAssetRequests.some((url) =>
|
||||
assetRequestIncludesTag(url, 'output')
|
||||
)
|
||||
)
|
||||
.toBe(true)
|
||||
await expectNoErrorsTab(comfyPage)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
cloudUploadRaceTest.describe(
|
||||
'Errors tab - Cloud missing media upload race',
|
||||
{ tag: '@cloud' },
|
||||
() => {
|
||||
cloudUploadRaceTest.beforeEach(async ({ comfyPage }) => {
|
||||
await enableErrorsTab(comfyPage)
|
||||
})
|
||||
|
||||
cloudUploadRaceTest(
|
||||
'does not surface missing media while dropped video upload is in progress',
|
||||
async ({ comfyFiles, comfyPage, markUploadedCloudAssetAvailable }) => {
|
||||
await comfyPage.nodeOps.clearGraph()
|
||||
const delayedUpload = await delayNextUpload(comfyPage)
|
||||
|
||||
await comfyPage.dragDrop.dragAndDropFile(plainVideoFileName, {
|
||||
dropPosition: graphDropPosition
|
||||
})
|
||||
await delayedUpload.waitForUploadStarted()
|
||||
comfyFiles.deleteAfterTest({
|
||||
filename: plainVideoFileName,
|
||||
type: 'input'
|
||||
})
|
||||
|
||||
await expectLoadVideoUploading(comfyPage)
|
||||
await expectNoMissingMediaDuringUpload(comfyPage)
|
||||
|
||||
markUploadedCloudAssetAvailable()
|
||||
await delayedUpload.finishUpload()
|
||||
await expect(getErrorOverlay(comfyPage)).toBeHidden()
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
@@ -57,7 +57,6 @@ type MetricKey =
|
||||
| 'frameDurationMs'
|
||||
| 'p95FrameDurationMs'
|
||||
| 'heapUsedBytes'
|
||||
| 'heapDeltaBytes'
|
||||
|
||||
interface MetricDef {
|
||||
key: MetricKey
|
||||
@@ -87,7 +86,6 @@ const REPORTED_METRICS: MetricDef[] = [
|
||||
{ key: 'scriptDurationMs', label: 'script duration', unit: 'ms' },
|
||||
{ key: 'totalBlockingTimeMs', label: 'TBT', unit: 'ms' },
|
||||
{ key: 'heapUsedBytes', label: 'heap used', unit: 'bytes' },
|
||||
{ key: 'heapDeltaBytes', label: 'heap delta', unit: 'bytes' },
|
||||
{ key: 'domNodes', label: 'DOM nodes', unit: '', minAbsDelta: 5 },
|
||||
{ key: 'eventListeners', label: 'event listeners', unit: '', minAbsDelta: 5 }
|
||||
]
|
||||
|
||||
@@ -141,6 +141,21 @@ describe('PointerZone', () => {
|
||||
y: 45
|
||||
})
|
||||
})
|
||||
|
||||
it('should preventDefault on wheel to block browser zoom on ctrl+wheel', () => {
|
||||
renderZone()
|
||||
const zone = getZone()
|
||||
|
||||
const event = new WheelEvent('wheel', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
deltaY: -1,
|
||||
ctrlKey: true
|
||||
})
|
||||
zone.dispatchEvent(event)
|
||||
|
||||
expect(event.defaultPrevented).toBe(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('isPanning watcher', () => {
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
@touchstart="handleTouchStart"
|
||||
@touchmove="handleTouchMove"
|
||||
@touchend="handleTouchEnd"
|
||||
@wheel="handleWheel"
|
||||
@wheel.prevent="handleWheel"
|
||||
@contextmenu.prevent
|
||||
/>
|
||||
</template>
|
||||
|
||||
@@ -1380,9 +1380,6 @@ export class LGraphNode
|
||||
|
||||
changeMode(modeTo: number): boolean {
|
||||
switch (modeTo) {
|
||||
case LGraphEventMode.ON_EVENT:
|
||||
break
|
||||
|
||||
case LGraphEventMode.ON_TRIGGER:
|
||||
this.addOnTriggerInput()
|
||||
this.addOnExecutedOutput()
|
||||
@@ -1399,7 +1396,8 @@ export class LGraphNode
|
||||
break
|
||||
|
||||
default:
|
||||
return false
|
||||
// Numeric default-accept: any caller-supplied numeric mode (including
|
||||
// the deprecated slot 1 / ON_EVENT) falls through and is assigned.
|
||||
break
|
||||
}
|
||||
this.mode = modeTo
|
||||
|
||||
@@ -122,7 +122,9 @@ export class LiteGraphGlobal {
|
||||
/** use with node_box_coloured_by_mode */
|
||||
NODE_MODES_COLORS = ['#666', '#422', '#333', '#224', '#626']
|
||||
ALWAYS = LGraphEventMode.ALWAYS
|
||||
ON_EVENT = LGraphEventMode.ON_EVENT
|
||||
// ON_EVENT is registered as a deprecation getter in the constructor — see
|
||||
// Object.defineProperty call below. The numeric slot (1) is preserved for
|
||||
// v2 ABI; the symbol will be removed in release N+1.
|
||||
NEVER = LGraphEventMode.NEVER
|
||||
ON_TRIGGER = LGraphEventMode.ON_TRIGGER
|
||||
|
||||
@@ -372,6 +374,15 @@ export class LiteGraphGlobal {
|
||||
|
||||
constructor() {
|
||||
Object.defineProperty(this, 'Classes', { writable: false })
|
||||
Object.defineProperty(this, 'ON_EVENT', {
|
||||
get() {
|
||||
console.warn(
|
||||
'LiteGraph.ON_EVENT is deprecated; numeric slot 1 is preserved for v2 ABI but the symbol will be removed in release N+1. ON_EVENT is a no-op mode — use NEVER to mute a node.'
|
||||
)
|
||||
return 1
|
||||
},
|
||||
configurable: true
|
||||
})
|
||||
}
|
||||
|
||||
Classes = {
|
||||
|
||||
@@ -82,7 +82,9 @@ export enum TitleMode {
|
||||
|
||||
export enum LGraphEventMode {
|
||||
ALWAYS = 0,
|
||||
ON_EVENT = 1,
|
||||
/** @deprecated No-op mode. Numeric slot 1 is preserved for v2 ABI; the
|
||||
* symbol will be removed in release N+1. Use NEVER to mute a node. */
|
||||
_UNUSED_1 = 1,
|
||||
NEVER = 2,
|
||||
ON_TRIGGER = 3,
|
||||
BYPASS = 4
|
||||
|
||||
Reference in New Issue
Block a user