Skip to content

Commit d8d0649

Browse files
committed
Merge branch 'main' of github.com:jbilcke-hf/clapper
2 parents e4ff8a6 + c0d7223 commit d8d0649

File tree

4 files changed

+87
-56
lines changed

4 files changed

+87
-56
lines changed

packages/app/src/app/api/resolve/providers/comfyui/index.ts

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ComfyUIWorkflowApiGraph,
1313
createPromptBuilder,
1414
} from './utils'
15+
import { ClapInputValueObject } from '@aitube/clap/dist/types'
1516

1617
export async function resolveSegment(
1718
request: ResolveRequest
@@ -72,33 +73,27 @@ export async function resolveSegment(
7273
)
7374
})
7475

75-
// Set main inputs
76-
comfyApiWorkflowPromptBuilder
77-
.input(
78-
(inputValues[ClapperComfyUiInputIds.PROMPT] as any).id,
79-
request.prompts.image.positive
80-
)
81-
.input(
82-
(inputValues[ClapperComfyUiInputIds.NEGATIVE_PROMPT] as any).id,
83-
request.prompts.image.negative
84-
)
85-
.input(
86-
(inputValues[ClapperComfyUiInputIds.WIDTH] as any).id,
87-
request.meta.width
88-
)
89-
.input(
90-
(inputValues[ClapperComfyUiInputIds.HEIGHT] as any).id,
91-
request.meta.height
92-
)
93-
.input(
94-
(inputValues[ClapperComfyUiInputIds.SEED] as any).id,
95-
generateSeed()
96-
)
76+
const mainInputs = [
77+
[ClapperComfyUiInputIds.PROMPT, request.prompts.image.positive],
78+
[ClapperComfyUiInputIds.NEGATIVE_PROMPT, request.prompts.image.negative],
79+
[ClapperComfyUiInputIds.WIDTH, request.meta.width],
80+
[ClapperComfyUiInputIds.HEIGHT, request.meta.height],
81+
[ClapperComfyUiInputIds.SEED, generateSeed()],
82+
]
83+
84+
mainInputs.forEach((mainInput) => {
85+
const inputId = (inputValues[mainInput[0]] as ClapInputValueObject).id
86+
const inputValue = mainInput[1]
87+
if (inputId) {
88+
comfyApiWorkflowPromptBuilder.input(inputId, inputValue)
89+
}
90+
})
9791

9892
// Set output
9993
comfyApiWorkflowPromptBuilder.setOutputNode(
10094
ClapperComfyUiInputIds.OUTPUT,
101-
(inputValues[ClapperComfyUiInputIds.OUTPUT] as any).id
95+
(inputValues[ClapperComfyUiInputIds.OUTPUT] as ClapInputValueObject)
96+
.id as string
10297
)
10398

10499
const pipeline = new CallWrapper(api, comfyApiWorkflowPromptBuilder)

packages/app/src/app/api/resolve/providers/comfyui/utils.ts

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -563,30 +563,42 @@ export function getInputsFromComfyUiWorkflow(workflowString: string): {
563563
const outputNode = workflowGraph.getOutputNode()
564564

565565
const inputValues = {
566-
[ClapperComfyUiInputIds.PROMPT]: {
567-
id: promptNodeInputs?.[0].id,
568-
label: `${promptNodeInputs?.[0].id} (from node ${promptNodeInputs?.[0].nodeId})`,
569-
},
570-
[ClapperComfyUiInputIds.NEGATIVE_PROMPT]: {
571-
id: negativePromptNodeInputs?.[0].id,
572-
label: `${negativePromptNodeInputs?.[0].id} (from node ${negativePromptNodeInputs?.[0].nodeId})`,
573-
},
574-
[ClapperComfyUiInputIds.WIDTH]: {
575-
id: widthNodeInputs?.[0].id,
576-
label: `${widthNodeInputs?.[0].id} (from node ${widthNodeInputs?.[0].nodeId})`,
577-
},
578-
[ClapperComfyUiInputIds.HEIGHT]: {
579-
id: heightNodeInputs?.[0].id,
580-
label: `${heightNodeInputs?.[0].id} (from node ${heightNodeInputs?.[0].nodeId})`,
581-
},
582-
[ClapperComfyUiInputIds.SEED]: {
583-
id: seedNodeInputs?.[0].id,
584-
label: `${seedNodeInputs?.[0].id} (from node ${seedNodeInputs?.[0].nodeId})`,
585-
},
586-
[ClapperComfyUiInputIds.OUTPUT]: {
587-
id: outputNode?.id,
588-
label: `${outputNode?._meta?.title} (id: ${outputNode?.id})`,
589-
},
566+
[ClapperComfyUiInputIds.PROMPT]: promptNodeInputs?.[0]
567+
? {
568+
id: promptNodeInputs?.[0].id,
569+
label: `${promptNodeInputs?.[0].id} (from node ${promptNodeInputs?.[0].nodeId})`,
570+
}
571+
: undefined,
572+
[ClapperComfyUiInputIds.NEGATIVE_PROMPT]: negativePromptNodeInputs?.[0]
573+
? {
574+
id: negativePromptNodeInputs?.[0].id,
575+
label: `${negativePromptNodeInputs?.[0].id} (from node ${negativePromptNodeInputs?.[0].nodeId})`,
576+
}
577+
: undefined,
578+
[ClapperComfyUiInputIds.WIDTH]: widthNodeInputs?.[0]
579+
? {
580+
id: widthNodeInputs?.[0].id,
581+
label: `${widthNodeInputs?.[0].id} (from node ${widthNodeInputs?.[0].nodeId})`,
582+
}
583+
: undefined,
584+
[ClapperComfyUiInputIds.HEIGHT]: heightNodeInputs?.[0]
585+
? {
586+
id: heightNodeInputs?.[0].id,
587+
label: `${heightNodeInputs?.[0].id} (from node ${heightNodeInputs?.[0].nodeId})`,
588+
}
589+
: undefined,
590+
[ClapperComfyUiInputIds.SEED]: seedNodeInputs?.[0]
591+
? {
592+
id: seedNodeInputs?.[0].id,
593+
label: `${seedNodeInputs?.[0].id} (from node ${seedNodeInputs?.[0].nodeId})`,
594+
}
595+
: undefined,
596+
[ClapperComfyUiInputIds.OUTPUT]: outputNode
597+
? {
598+
id: outputNode?.id,
599+
label: `${outputNode?._meta?.title} (id: ${outputNode?.id})`,
600+
}
601+
: undefined,
590602
}
591603

592604
const inputLabels = {

packages/app/src/lib/utils/getTypeAndExtension.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,29 @@ test('getTypeAndExtension', () => {
2929
outputType: ClapOutputType.VIDEO,
3030
})
3131
})
32+
33+
/**
34+
* Related to the `Maximum call stack size exceeded` issue
35+
* when using RegExp, now with string/array manipulation is
36+
* much faster and the `stack` error solved; I wasn't able to easily
37+
* replicate the stack size error in vitest env, seems happening only
38+
* in Next env; so only a "performance" test is done.
39+
*
40+
* Issue: https://github.com/jbilcke-hf/clapper/issues/72
41+
*/
42+
test('getTypeAndExtension should be fast for long uris', () => {
43+
const startTime = Date.now()
44+
const longBase64String = 'a'.repeat(500_000_000)
45+
const dataUri = `data:image/png;base64,${longBase64String}`
46+
const result = getTypeAndExtension(dataUri)
47+
expect(result).toStrictEqual({
48+
assetFileFormat: 'image/png',
49+
category: 'image',
50+
extension: 'png',
51+
outputType: ClapOutputType.IMAGE,
52+
})
53+
const endTime = Date.now()
54+
const duration = endTime - startTime
55+
// Original regexp approach was running around ~350ms; new one is around ~70ms
56+
expect(duration).toBeLessThan(200)
57+
})

packages/app/src/lib/utils/getTypeAndExtension.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ClapOutputType } from '@aitube/clap'
22

33
/**
4-
* break a base64 string into sub-components
4+
* break a base64 data uri string into sub-components
55
*/
66
export function getTypeAndExtension(base64: string = ''): {
77
// category eg. video, audio, text
@@ -15,17 +15,15 @@ export function getTypeAndExtension(base64: string = ''): {
1515

1616
outputType: ClapOutputType
1717
} {
18-
// Regular expression to extract the MIME type and the base64 data
19-
const matches = base64.match(/^data:([A-Za-z-+0-9/]+);base64,(.+)$/)
20-
21-
if (!matches || matches.length !== 3) {
22-
throw new Error('Invalid base64 string')
18+
if (!base64.startsWith('data:') || !base64.includes('base64,')) {
19+
throw new Error('Invalid base64 data uri provided.')
2320
}
2421

25-
const assetFileFormat = matches[1] || ''
22+
const base64Index = base64.indexOf('base64,')
23+
const mimeType = base64.slice(5, base64Index - 1)
2624

2725
// this should be enough for most media formats (jpeg, png, webp, mp4)
28-
const [category, extension] = assetFileFormat.split('/')
26+
const [category, extension] = mimeType.split('/')
2927

3028
let outputType = ClapOutputType.TEXT
3129

@@ -39,7 +37,7 @@ export function getTypeAndExtension(base64: string = ''): {
3937

4038
return {
4139
category,
42-
assetFileFormat,
40+
assetFileFormat: mimeType,
4341
extension,
4442
outputType,
4543
}

0 commit comments

Comments
 (0)