@unoverse-platform/studio 0.1.35 → 0.1.36
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/package.json
CHANGED
|
@@ -373,6 +373,16 @@ export function TemplatesView({
|
|
|
373
373
|
[canConnect, rawConn],
|
|
374
374
|
);
|
|
375
375
|
|
|
376
|
+
// The workflow can OVERRIDE the manual pick (WORKFLOW_STARTED metadata.template →
|
|
377
|
+
// store.activeTemplate) with a BARE name — so the org must be resolved for whichever
|
|
378
|
+
// template is actually loading, not the picked one, or the resources/read goes out
|
|
379
|
+
// org-less and the server refuses it ("template address needs its org").
|
|
380
|
+
const activeName = conn.activeTemplate ?? selected;
|
|
381
|
+
const activeDef = useMemo(
|
|
382
|
+
() => (activeName === selected ? selectedDef : (templates.find((t) => t.name === activeName) ?? selectedDef)),
|
|
383
|
+
[templates, activeName, selected, selectedDef],
|
|
384
|
+
);
|
|
385
|
+
|
|
376
386
|
// The `voice` native service (§2e-1) now lives INSIDE the SDK renderer (shared by every
|
|
377
387
|
// host — see StreamedUnoverseTemplate). The host only DECLARES the app is voice (off its
|
|
378
388
|
// manifest `service`) and hands the renderer the connection identity it already holds;
|
|
@@ -1005,6 +1015,11 @@ export function TemplatesView({
|
|
|
1005
1015
|
conversationId={session.conversationId}
|
|
1006
1016
|
onStatus={setNativeStatus}
|
|
1007
1017
|
/>
|
|
1018
|
+
) : !activeDef && templates.length === 0 ? (
|
|
1019
|
+
/* The workflow can announce its template BEFORE /dev/templates answers.
|
|
1020
|
+
Reading it org-less is a guaranteed server refusal, so hold one beat
|
|
1021
|
+
until the list arrives and the org can be resolved. */
|
|
1022
|
+
null
|
|
1008
1023
|
) : (
|
|
1009
1024
|
<StreamedUnoverseTemplate
|
|
1010
1025
|
client={client}
|
|
@@ -1012,7 +1027,7 @@ export function TemplatesView({
|
|
|
1012
1027
|
// The workflow can SELECT the template (WORKFLOW_STARTED metadata.template →
|
|
1013
1028
|
// store.activeTemplate); that overrides the manual pick. Loaded via the
|
|
1014
1029
|
// official resources/read unoverse://templates/{name} (templates = MCP apps).
|
|
1015
|
-
uri={`unoverse://templates/${
|
|
1030
|
+
uri={`unoverse://templates/${activeDef?.org ? `${activeDef.org}/` : ""}${activeName}`}
|
|
1016
1031
|
theme={theme}
|
|
1017
1032
|
// Voice state arrives via TEMPLATE STATE (the service is a producer inside
|
|
1018
1033
|
// the renderer); startCall/endCall/toggleMute are answered there too.
|
|
@@ -154,8 +154,10 @@ export class UnoverseClient {
|
|
|
154
154
|
})();
|
|
155
155
|
this.inflight.set(uri, read);
|
|
156
156
|
// Cleared either way: a failed read must not be remembered as pending forever, or the
|
|
157
|
-
// next asker waits on a promise that will never resolve again.
|
|
158
|
-
read.finally(
|
|
157
|
+
// next asker waits on a promise that will never resolve again. The catch is REQUIRED:
|
|
158
|
+
// a bare `read.finally()` forks a second promise chain that nobody awaits, so every
|
|
159
|
+
// failed read also surfaced as an Uncaught (in promise) even when the caller handled it.
|
|
160
|
+
read.catch(() => {}).finally(() => this.inflight.delete(uri));
|
|
159
161
|
return read;
|
|
160
162
|
}
|
|
161
163
|
|
|
@@ -177,7 +179,7 @@ export class UnoverseClient {
|
|
|
177
179
|
return theme;
|
|
178
180
|
})();
|
|
179
181
|
this.themeInflight.set(name, read);
|
|
180
|
-
read.finally(() => this.themeInflight.delete(name));
|
|
182
|
+
read.catch(() => {}).finally(() => this.themeInflight.delete(name));
|
|
181
183
|
return read;
|
|
182
184
|
}
|
|
183
185
|
|