@deepblend/dsh-blender-ui 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +125 -4
- package/lib/index.js +19 -0
- package/package.json +2 -2
package/lib/client.js
CHANGED
|
@@ -355,6 +355,14 @@ window.__ModuleLoader__.load({
|
|
|
355
355
|
'editor.unknownSettings': '这张预览缺少实测渲染设置,无法比较编辑差异。',
|
|
356
356
|
'editor.missingBaseline': '没有同相机、同帧和同渲染设置的编辑前预览,暂时无法比较差异。',
|
|
357
357
|
'editor.choose': '选择一个对象,调整后应用并查看真实预览。',
|
|
358
|
+
'assembly.title': '调整整套模型',
|
|
359
|
+
'assembly.help': '尺寸会联动配方中的部件,保留独立修改的材质、倒角和摄影设置。保存后生成新版本和预览。',
|
|
360
|
+
'assembly.save': '保存整套尺寸并预览',
|
|
361
|
+
'assembly.retry': '重试同一次保存',
|
|
362
|
+
'assembly.conflict': '部分受控几何已被单独修改,请先恢复对应部件;整套尺寸尚未保存。',
|
|
363
|
+
'assembly.stale': '当前作品已有新版本。草稿已保留,请重新载入后再修改。',
|
|
364
|
+
'assembly.otherDraft': '请先保存或放弃其他未提交的编辑。',
|
|
365
|
+
'assembly.photoKept': '已保留自定义摄影,请确认新尺寸下的构图。',
|
|
358
366
|
'editor.position': '位置(mm)',
|
|
359
367
|
'editor.rotation': '旋转(°)',
|
|
360
368
|
'editor.geometry': '形状与轮廓',
|
|
@@ -371,6 +379,9 @@ window.__ModuleLoader__.load({
|
|
|
371
379
|
'editor.animated': '动画控制的通道已禁用。',
|
|
372
380
|
'editor.invalid': '{field} 的值无效。',
|
|
373
381
|
'editor.size': '尺寸(mm)',
|
|
382
|
+
'editor.boxWidth': '宽(mm)',
|
|
383
|
+
'editor.boxDepth': '深(mm)',
|
|
384
|
+
'editor.boxHeight': '高(mm)',
|
|
374
385
|
'editor.radius': '半径(mm)',
|
|
375
386
|
'editor.handledCup': '带把手杯体',
|
|
376
387
|
'editor.wallThickness': '杯壁厚度(mm)',
|
|
@@ -943,6 +954,14 @@ window.__ModuleLoader__.load({
|
|
|
943
954
|
'editor.unknownSettings': 'Measured render settings are missing. This preview cannot establish the edit difference.',
|
|
944
955
|
'editor.missingBaseline': 'No before preview has the same camera, frame and measured render settings. The edit difference is unavailable.',
|
|
945
956
|
'editor.choose': 'Select an object, adjust its settings, then apply and view a real preview.',
|
|
957
|
+
'assembly.title': 'Resize the assembly',
|
|
958
|
+
'assembly.help': 'Recipe parts follow the dimensions. Independent materials, bevels and photography are retained. Saving creates a new revision and preview.',
|
|
959
|
+
'assembly.save': 'Save assembly dimensions and preview',
|
|
960
|
+
'assembly.retry': 'Retry the same save',
|
|
961
|
+
'assembly.conflict': 'Controlled geometry was edited separately. Restore those parts before resizing; nothing has been saved.',
|
|
962
|
+
'assembly.stale': 'The work has a newer revision. Your draft is retained; reload it before editing.',
|
|
963
|
+
'assembly.otherDraft': 'Save or discard other unsaved edits first.',
|
|
964
|
+
'assembly.photoKept': 'Custom photography was preserved. Check framing at the new dimensions.',
|
|
946
965
|
'editor.position': 'Position (mm)',
|
|
947
966
|
'editor.rotation': 'Rotation (°)',
|
|
948
967
|
'editor.geometry': 'Shape and profile',
|
|
@@ -959,6 +978,9 @@ window.__ModuleLoader__.load({
|
|
|
959
978
|
'editor.animated': 'Channels driven by animation are disabled.',
|
|
960
979
|
'editor.invalid': 'Invalid value for {field}.',
|
|
961
980
|
'editor.size': 'Size (mm)',
|
|
981
|
+
'editor.boxWidth': 'Width (mm)',
|
|
982
|
+
'editor.boxDepth': 'Depth (mm)',
|
|
983
|
+
'editor.boxHeight': 'Height (mm)',
|
|
962
984
|
'editor.radius': 'Radius (mm)',
|
|
963
985
|
'editor.handledCup': 'Handled cup',
|
|
964
986
|
'editor.wallThickness': 'Wall thickness (mm)',
|
|
@@ -1386,7 +1408,7 @@ window.__ModuleLoader__.load({
|
|
|
1386
1408
|
|
|
1387
1409
|
/** Every DeepBlend wire tool name this package draws a card for. */
|
|
1388
1410
|
const TOOL_CARD_KEYS = [
|
|
1389
|
-
'blender_capabilities', 'blender_recipe_list', 'blender_project_create', 'blender_project_get',
|
|
1411
|
+
'blender_capabilities', 'blender_recipe_list', 'blender_recipe_parameters', 'blender_project_create', 'blender_project_get',
|
|
1390
1412
|
'blender_scene_get', 'blender_scene_patch', 'blender_preview_render',
|
|
1391
1413
|
'blender_scene_validate', 'blender_revision_restore', 'blender_asset_ingest',
|
|
1392
1414
|
'blender_preview_views', 'blender_visual_review',
|
|
@@ -2054,7 +2076,13 @@ window.__ModuleLoader__.load({
|
|
|
2054
2076
|
}
|
|
2055
2077
|
const generator = draft.entity.generator
|
|
2056
2078
|
if (generator) {
|
|
2079
|
+
if (generator.dimensions !== undefined) {
|
|
2080
|
+
if (!['cube', 'rounded_box'].includes(generator.shape) || generator.size !== undefined
|
|
2081
|
+
|| !Array.isArray(generator.dimensions) || generator.dimensions.length !== 3) bad('dimensions')
|
|
2082
|
+
else generator.dimensions.forEach((value, axis) => scalar(value, `dimensions.${EDITOR_AXES[axis]}`, Number.MIN_VALUE))
|
|
2083
|
+
}
|
|
2057
2084
|
for (const key of GENERATOR_FIELDS[generator.shape] || []) {
|
|
2085
|
+
if (key === 'size' && generator.dimensions !== undefined) continue
|
|
2058
2086
|
const bounds = generatorIntegerBounds(generator, key)
|
|
2059
2087
|
if (bounds?.[2] && generator[key] % bounds[2]) bad(key)
|
|
2060
2088
|
scalar(generator[key], key, key === 'rootTension' ? 1 : bounds ? bounds[0] : Number.MIN_VALUE,
|
|
@@ -2478,6 +2506,19 @@ window.__ModuleLoader__.load({
|
|
|
2478
2506
|
|| photographyDirty(photographyDraftFor(state))
|
|
2479
2507
|
|| Boolean(state.assetDrafts?.[state.activeProjectId])
|
|
2480
2508
|
|| state.forms.patch !== null
|
|
2509
|
+
|| assemblyDirty(assemblyDraftFor(state))
|
|
2510
|
+
}
|
|
2511
|
+
const assemblyKey = state => JSON.stringify([state.projectsRoot, state.activeProjectId])
|
|
2512
|
+
const assemblyDraftFor = state => state.assemblyDrafts?.[assemblyKey(state)] || null
|
|
2513
|
+
const assemblyDirty = draft => Boolean(draft && Object.entries(draft.values).some(([id, value]) => value === '' || Number(value) !== draft.original[id]))
|
|
2514
|
+
const assemblyInvalid = draft => !draft || draft.parameters.some(parameter => {
|
|
2515
|
+
const raw = draft.values[parameter.id], value = Number(raw)
|
|
2516
|
+
return raw === '' || !Number.isFinite(value) || value < parameter.minimum || value > parameter.maximum
|
|
2517
|
+
})
|
|
2518
|
+
function createAssemblyDraft(source, projectsRoot) {
|
|
2519
|
+
const values = Object.fromEntries(source.parameters.map(parameter => [parameter.id, parameter.value]))
|
|
2520
|
+
return { projectId: source.projectId, projectsRoot, baseRevision: source.revision,
|
|
2521
|
+
parameters: editorClone(source.parameters), values, original: { ...values }, idempotencyKey: newCreationKey(), attempt: null }
|
|
2481
2522
|
}
|
|
2482
2523
|
function briefValid(draft) {
|
|
2483
2524
|
return Boolean(draft && typeof draft.goal === 'string' && draft.goal.length <= 2000 && draft.referenceImages.length <= 4
|
|
@@ -2724,10 +2765,11 @@ window.__ModuleLoader__.load({
|
|
|
2724
2765
|
editorDrafts: {},
|
|
2725
2766
|
editorLastEdits: {},
|
|
2726
2767
|
editorComparison: null,
|
|
2768
|
+
assemblyDrafts: {},
|
|
2727
2769
|
patchDrafts: {},
|
|
2728
2770
|
recipeChoices: [],
|
|
2729
2771
|
forms: { title: '', goal: '', recipe: null, recipeParameters: {}, patch: null, frameStart: '', frameEnd: '', profile: 'preview' },
|
|
2730
|
-
busy: { create: false, patch: false, editor: false, render: false, restore: false },
|
|
2772
|
+
busy: { create: false, patch: false, editor: false, assembly: false, render: false, restore: false },
|
|
2731
2773
|
notices: { projects: null, scene: null, preview: null, jobs: null, revisions: null },
|
|
2732
2774
|
}
|
|
2733
2775
|
}
|
|
@@ -2989,6 +3031,13 @@ window.__ModuleLoader__.load({
|
|
|
2989
3031
|
if (sequence !== loadSequence || projectId !== target()) return
|
|
2990
3032
|
if (active !== data.activeProjectId) patch.forms = { ...data.forms, patch: data.patchDrafts[active] ?? null }
|
|
2991
3033
|
if (patch.selected?.scene && active) {
|
|
3034
|
+
const source = patch.selected.recipeParameters
|
|
3035
|
+
if (source?.available === true && source.projectId === active && source.revision === patch.selected.scene.revision) {
|
|
3036
|
+
const key = JSON.stringify([patch.projectsRoot, active]), draft = data.assemblyDrafts[key]
|
|
3037
|
+
if ((!draft || !assemblyDirty(draft)) && !data.busy.assembly) {
|
|
3038
|
+
patch.assemblyDrafts = { ...data.assemblyDrafts, [key]: createAssemblyDraft(source, patch.projectsRoot) }
|
|
3039
|
+
}
|
|
3040
|
+
}
|
|
2992
3041
|
const photography = data.photographyDrafts[active]
|
|
2993
3042
|
if ((!photography || !photographyDirty(photography)) && !data.photographyWork[active]?.saving) {
|
|
2994
3043
|
patch.photographyDrafts = { ...data.photographyDrafts, [active]: createPhotographyDraft(patch.selected.scene, active, photography, patch.projectsRoot) }
|
|
@@ -3159,6 +3208,48 @@ window.__ModuleLoader__.load({
|
|
|
3159
3208
|
}
|
|
3160
3209
|
}
|
|
3161
3210
|
const actions = {
|
|
3211
|
+
setAssemblyValue: (id, value) => {
|
|
3212
|
+
const draft = assemblyDraftFor(data)
|
|
3213
|
+
if (!draft || data.busy.assembly || draft.attempt || !draft.parameters.some(parameter => parameter.id === id)) return
|
|
3214
|
+
set({ assemblyDrafts: { ...data.assemblyDrafts, [assemblyKey(data)]: { ...draft, values: { ...draft.values, [id]: value } } } })
|
|
3215
|
+
},
|
|
3216
|
+
resetAssembly: () => {
|
|
3217
|
+
const source = data.selected?.recipeParameters
|
|
3218
|
+
if (!source?.available || data.busy.assembly) return
|
|
3219
|
+
set({ assemblyDrafts: { ...data.assemblyDrafts, [assemblyKey(data)]: createAssemblyDraft(source, data.projectsRoot) } })
|
|
3220
|
+
},
|
|
3221
|
+
saveAssembly: async () => {
|
|
3222
|
+
const draft = assemblyDraftFor(data), source = data.selected?.recipeParameters
|
|
3223
|
+
if (!draft || data.busy.assembly || assemblyInvalid(draft) || !assemblyDirty(draft)) return
|
|
3224
|
+
if (!draft.attempt && (draft.baseRevision !== source?.revision || source?.conflicts?.length
|
|
3225
|
+
|| projectHasUnsavedDrafts({ ...data, assemblyDrafts: {} }))) return
|
|
3226
|
+
const key = assemblyKey(data), body = draft.attempt || { baseRevision: draft.baseRevision,
|
|
3227
|
+
projectsRoot: draft.projectsRoot, idempotencyKey: draft.idempotencyKey,
|
|
3228
|
+
parameters: Object.fromEntries(Object.entries(draft.values).map(([id, value]) => [id, Number(value)])) }
|
|
3229
|
+
set({ assemblyDrafts: { ...data.assemblyDrafts, [key]: { ...draft, attempt: body } } })
|
|
3230
|
+
setIn('busy', 'assembly', true)
|
|
3231
|
+
const outcome = await postJson(fetchImpl, projectRoute(draft.projectId, '/recipe-parameters'), body)
|
|
3232
|
+
setIn('busy', 'assembly', false)
|
|
3233
|
+
if (outcome.ok) {
|
|
3234
|
+
const drafts = { ...data.assemblyDrafts }; delete drafts[key]
|
|
3235
|
+
set({ assemblyDrafts: drafts })
|
|
3236
|
+
if (target() === draft.projectId && data.projectsRoot === draft.projectsRoot) {
|
|
3237
|
+
const revision = outcome.payload.revision.revision
|
|
3238
|
+
const notice = { ok: true, kind: 'recipe-parameters', message: t('scene.committed', { revision,
|
|
3239
|
+
digest: shortDigest(outcome.payload.revision.digest) }) + (outcome.payload.revision.preservedCameraIds?.length ? ` ${t('assembly.photoKept')}` : '') }
|
|
3240
|
+
set({ view: 'preview', compareMode: 'revisions', compareLeft: draft.baseRevision, compareRight: revision,
|
|
3241
|
+
notices: { ...data.notices, scene: notice, preview: notice } })
|
|
3242
|
+
}
|
|
3243
|
+
reload()
|
|
3244
|
+
} else {
|
|
3245
|
+
const uncertain = outcome.error.code === 'UI_FETCH_FAILED' || /^HTTP_5/.test(outcome.error.code)
|
|
3246
|
+
set({ assemblyDrafts: { ...data.assemblyDrafts, [key]: { ...draft, attempt: uncertain ? body : null } } })
|
|
3247
|
+
if (target() === draft.projectId && data.projectsRoot === draft.projectsRoot) {
|
|
3248
|
+
setIn('notices', 'scene', { ok: false, message: `${outcome.error.code}: ${outcome.error.message}` })
|
|
3249
|
+
if (outcome.error.code === 'REVISION_CONFLICT') reload()
|
|
3250
|
+
}
|
|
3251
|
+
}
|
|
3252
|
+
},
|
|
3162
3253
|
acceptsFileChoice,
|
|
3163
3254
|
setAppearance: value => {
|
|
3164
3255
|
if (!APPEARANCES.includes(value)) return
|
|
@@ -4358,6 +4449,32 @@ window.__ModuleLoader__.load({
|
|
|
4358
4449
|
}, result.message)
|
|
4359
4450
|
}
|
|
4360
4451
|
|
|
4452
|
+
function AssemblyEditor(ctx) {
|
|
4453
|
+
const { state, actions } = ctx, source = state.selected?.recipeParameters, draft = assemblyDraftFor(state)
|
|
4454
|
+
if (!source) return null
|
|
4455
|
+
if (source.error) return el('div', { className: 'db-card', 'data-assembly-editor': true },
|
|
4456
|
+
el('h4', null, t('assembly.title')), ErrorBox({ error: source.error }))
|
|
4457
|
+
if (!source.available || !draft) return null
|
|
4458
|
+
const stale = draft.baseRevision !== state.selected.scene.revision
|
|
4459
|
+
const otherDirty = projectHasUnsavedDrafts({ ...state, assemblyDrafts: {} })
|
|
4460
|
+
const blocked = state.busy.assembly || !draft.attempt && (stale || source.conflicts?.length || otherDirty)
|
|
4461
|
+
return el('div', { className: 'db-card', 'data-assembly-editor': true,
|
|
4462
|
+
'data-assembly-base-revision': draft.baseRevision, 'data-assembly-dirty': String(assemblyDirty(draft)) },
|
|
4463
|
+
el('h4', null, t('assembly.title')), el('p', { className: 'db-muted' }, t('assembly.help')),
|
|
4464
|
+
source.conflicts?.length ? el('div', { className: 'db-error' }, t('assembly.conflict'),
|
|
4465
|
+
el('div', { className: 'db-inline' }, [...new Set(source.conflicts.map(conflict => conflict.entityId))].map(entityId =>
|
|
4466
|
+
Button({ key: entityId, action: `assembly-conflict:${entityId}`, onClick: () => actions.selectEditorEntity(entityId), children: entityId })))) : null,
|
|
4467
|
+
stale ? el('div', { className: 'db-error' }, t('assembly.stale')) : null,
|
|
4468
|
+
otherDirty ? el('div', { className: 'db-muted' }, t('assembly.otherDraft')) : null,
|
|
4469
|
+
el('div', { className: 'db-grid' }, draft.parameters.map(parameter => el('label', { key: parameter.id },
|
|
4470
|
+
parameter.title, el('input', { type: 'number', className: 'db-input', 'data-field': `assembly-${parameter.id}`,
|
|
4471
|
+
min: parameter.minimum, max: parameter.maximum, step: 'any', value: draft.values[parameter.id],
|
|
4472
|
+
disabled: state.busy.assembly || Boolean(draft.attempt), onInput: event => actions.setAssemblyValue(parameter.id, event.currentTarget.value) })))),
|
|
4473
|
+
el('div', { className: 'db-inline' }, Button({ action: 'assembly-save', disabled: Boolean(blocked) || assemblyInvalid(draft) || !assemblyDirty(draft),
|
|
4474
|
+
onClick: actions.saveAssembly, children: draft.attempt ? t('assembly.retry') : t('assembly.save') }),
|
|
4475
|
+
Button({ action: 'assembly-reset', disabled: state.busy.assembly, onClick: actions.resetAssembly, children: t('editor.reset') })))
|
|
4476
|
+
}
|
|
4477
|
+
|
|
4361
4478
|
function SceneEditor(ctx) {
|
|
4362
4479
|
const { state, actions } = ctx, draft = editorDraftFor(state)
|
|
4363
4480
|
const lastEdit = state.editorLastEdits?.[state.activeProjectId]
|
|
@@ -4455,7 +4572,11 @@ window.__ModuleLoader__.load({
|
|
|
4455
4572
|
el('p', { className: 'db-muted', key: 'local-size' }, t('editor.localDimensions', { scale: (draft.entity.transform.scale || [1, 1, 1]).join(' × ') })),
|
|
4456
4573
|
geometry.shape === 'rounded_box' ? el('p', { className: 'db-muted', key: 'rounded' }, t('editor.roundedRequired')) : null,
|
|
4457
4574
|
geometry.shape === 'handled_cup' ? el('p', { className: 'db-muted', key: 'cup-help' }, t('editor.cupHelp')) : null,
|
|
4458
|
-
...(GENERATOR_FIELDS[geometry.shape] || []).filter(key =>
|
|
4575
|
+
...(GENERATOR_FIELDS[geometry.shape] || []).filter(key => !(key === 'size' && geometry.dimensions !== undefined)
|
|
4576
|
+
&& (geometry.shape !== 'handled_cup' || !CUP_ADVANCED_FIELDS.includes(key))).map(geometryField),
|
|
4577
|
+
...(geometry.dimensions !== undefined ? [t('editor.boxWidth'), t('editor.boxDepth'), t('editor.boxHeight')].map((label, index) => numeric(
|
|
4578
|
+
label, `editor-generator-dimensions-${EDITOR_AXES[index]}`, geometry.dimensions[index],
|
|
4579
|
+
value => actions.updateEditor('generator', ['dimensions', index], value), { factor: 1000, min: Number.MIN_VALUE })) : []),
|
|
4459
4580
|
geometry.shape === 'handled_cup' ? el('details', { key: 'cup-advanced' },
|
|
4460
4581
|
el('summary', null, t('editor.cupAdvanced')), ...CUP_ADVANCED_FIELDS.map(geometryField)) : null,
|
|
4461
4582
|
toggle(t('editor.bevel'), 'editor-generator-bevel', Boolean(geometry.bevel), value => actions.updateEditor('generator', ['bevel'], value ? { width: 0.001, segments: 3 } : undefined), geometry.shape === 'rounded_box'),
|
|
@@ -4839,7 +4960,7 @@ window.__ModuleLoader__.load({
|
|
|
4839
4960
|
el('span', { className: 'db-muted db-mono' }, String(asset.path || '')))),
|
|
4840
4961
|
)),
|
|
4841
4962
|
el('section', { className: 'db-scene-inspector', 'aria-label': t('scene.inspector') },
|
|
4842
|
-
SceneEditor(ctx),
|
|
4963
|
+
AssemblyEditor(ctx), SceneEditor(ctx),
|
|
4843
4964
|
PhotographyEditor(ctx),
|
|
4844
4965
|
AssetsView(ctx),
|
|
4845
4966
|
el('details', { key: advancedDisclosure, 'data-disclosure': advancedDisclosure, open: state.disclosures?.[advancedDisclosure] ?? false,
|
package/lib/index.js
CHANGED
|
@@ -426,6 +426,7 @@ export function statusForError(error) {
|
|
|
426
426
|
if (referenceStatuses[error.code]) return referenceStatuses[error.code]
|
|
427
427
|
if (error.code === 'RECIPE_NOT_FOUND') return 404
|
|
428
428
|
if (error.code === 'RECIPE_CHANGED' || error.code === 'RECIPE_ID_CONFLICT') return 409
|
|
429
|
+
if (error.code === 'RECIPE_PARAMETER_CONFLICT') return 409
|
|
429
430
|
if (error.code?.startsWith('RECIPE_')) return 400
|
|
430
431
|
switch (error.code) {
|
|
431
432
|
case BlenderErrorCode.PROJECT_NOT_FOUND:
|
|
@@ -439,6 +440,7 @@ export function statusForError(error) {
|
|
|
439
440
|
return 400
|
|
440
441
|
case BlenderErrorCode.RENDER_JOB_CONFLICT:
|
|
441
442
|
case BlenderErrorCode.REVISION_CONFLICT:
|
|
443
|
+
case BlenderErrorCode.SCENE_FEATURE_UNSUPPORTED:
|
|
442
444
|
return 409
|
|
443
445
|
default:
|
|
444
446
|
return 500
|
|
@@ -827,6 +829,16 @@ export function createHandlers(ctx) {
|
|
|
827
829
|
return { revision: result }
|
|
828
830
|
},
|
|
829
831
|
|
|
832
|
+
'project.recipeParameters': async ({ params, query }) => {
|
|
833
|
+
if (studio().recipeParameterEditingSupported !== true) throw new BlenderError('UI_HOST_API_STALE', 'Update the Host to edit assembly dimensions')
|
|
834
|
+
return studio().getRecipeParameters(params.projectId, { revision: query.revision })
|
|
835
|
+
},
|
|
836
|
+
'project.recipeParameters.update': async ({ params, body }) => {
|
|
837
|
+
if (studio().recipeParameterEditingSupported !== true) throw new BlenderError('UI_HOST_API_STALE', 'Update the Host to edit assembly dimensions')
|
|
838
|
+
return { revision: await studio().updateRecipeParameters({ ...body, projectId: params.projectId,
|
|
839
|
+
saveCheckpoint: true, renderPreview: true }) }
|
|
840
|
+
},
|
|
841
|
+
|
|
830
842
|
'project.restore': async ({ params, body }) => {
|
|
831
843
|
const result = await studio().restoreRevision({
|
|
832
844
|
projectId: params.projectId,
|
|
@@ -917,7 +929,14 @@ async function buildProjectState(studio, projectId, revision, threshold) {
|
|
|
917
929
|
const scene = await studio.getScene(projectId, { revision: requested, full: true })
|
|
918
930
|
const jobs = await studio.listJobs({ projectId })
|
|
919
931
|
const qa = await studio.getQaRecord({ projectId, revision: scene.revision })
|
|
932
|
+
let recipeParameters = null
|
|
933
|
+
if (studio.recipeParameterEditingSupported === true) {
|
|
934
|
+
try { recipeParameters = await studio.getRecipeParameters(projectId, { revision: scene.revision }) }
|
|
935
|
+
catch (error) { recipeParameters = { projectId, revision: scene.revision, available: false,
|
|
936
|
+
error: { code: error.code ?? 'RECIPE_LOCK_INVALID', message: error.message } } }
|
|
937
|
+
}
|
|
920
938
|
return {
|
|
939
|
+
recipeParameters,
|
|
921
940
|
project: buildProjectView({
|
|
922
941
|
projectId,
|
|
923
942
|
title: overview.title,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepblend/dsh-blender-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "DeepBlend workbench UI: Host half (typed HTTP API) and Web Client half (sidebar, panels, tool cards).",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
}
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@deepblend/dsh-blender-contracts": "0.
|
|
22
|
+
"@deepblend/dsh-blender-contracts": "0.6.0"
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"repository": {
|