@almadar/ui 4.11.0 → 4.12.1
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/dist/avl/index.cjs +133 -23
- package/dist/avl/index.js +133 -23
- package/dist/components/index.cjs +12 -1
- package/dist/components/index.js +12 -1
- package/dist/context/index.cjs +12 -1
- package/dist/context/index.js +12 -1
- package/dist/hooks/index.cjs +12 -1
- package/dist/hooks/index.js +12 -1
- package/dist/hooks/useUISlots.d.ts +14 -0
- package/dist/runtime/embedded-traits.d.ts +32 -0
- package/dist/runtime/index.cjs +123 -22
- package/dist/runtime/index.js +123 -22
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -4492,6 +4492,16 @@ function useUISlotManager() {
|
|
|
4492
4492
|
},
|
|
4493
4493
|
[]
|
|
4494
4494
|
);
|
|
4495
|
+
const updateTraitContent = React128.useCallback(
|
|
4496
|
+
(traitName, content) => {
|
|
4497
|
+
const id = generateId();
|
|
4498
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
4499
|
+
indexTraitRender(traitName, fullContent);
|
|
4500
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
4501
|
+
return id;
|
|
4502
|
+
},
|
|
4503
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
4504
|
+
);
|
|
4495
4505
|
return {
|
|
4496
4506
|
slots,
|
|
4497
4507
|
render,
|
|
@@ -4503,7 +4513,8 @@ function useUISlotManager() {
|
|
|
4503
4513
|
hasContent,
|
|
4504
4514
|
getContent,
|
|
4505
4515
|
getTraitContent,
|
|
4506
|
-
subscribeTrait
|
|
4516
|
+
subscribeTrait,
|
|
4517
|
+
updateTraitContent
|
|
4507
4518
|
};
|
|
4508
4519
|
}
|
|
4509
4520
|
var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
@@ -51542,6 +51553,76 @@ function useResolvedSchema(schema, pageName) {
|
|
|
51542
51553
|
return result;
|
|
51543
51554
|
}
|
|
51544
51555
|
|
|
51556
|
+
// runtime/embedded-traits.ts
|
|
51557
|
+
var TRAIT_BINDING_PREFIX = "@trait.";
|
|
51558
|
+
function collectTraitRefsFromValue(value, into) {
|
|
51559
|
+
if (value === null || value === void 0) return;
|
|
51560
|
+
if (typeof value === "string") {
|
|
51561
|
+
if (value.startsWith(TRAIT_BINDING_PREFIX)) {
|
|
51562
|
+
const rest = value.slice(TRAIT_BINDING_PREFIX.length);
|
|
51563
|
+
const dot = rest.indexOf(".");
|
|
51564
|
+
const traitName = dot === -1 ? rest : rest.slice(0, dot);
|
|
51565
|
+
if (traitName.length > 0) into.add(traitName);
|
|
51566
|
+
}
|
|
51567
|
+
return;
|
|
51568
|
+
}
|
|
51569
|
+
if (Array.isArray(value)) {
|
|
51570
|
+
for (const item of value) collectTraitRefsFromValue(item, into);
|
|
51571
|
+
return;
|
|
51572
|
+
}
|
|
51573
|
+
if (typeof value === "object") {
|
|
51574
|
+
for (const v of Object.values(value)) {
|
|
51575
|
+
collectTraitRefsFromValue(v, into);
|
|
51576
|
+
}
|
|
51577
|
+
}
|
|
51578
|
+
}
|
|
51579
|
+
function collectTraitRefsFromEffects(effects, into) {
|
|
51580
|
+
if (!effects) return;
|
|
51581
|
+
for (const effect of effects) {
|
|
51582
|
+
if (!Array.isArray(effect)) continue;
|
|
51583
|
+
if (effect[0] === "render-ui" && effect.length >= 3) {
|
|
51584
|
+
collectTraitRefsFromValue(effect[2], into);
|
|
51585
|
+
continue;
|
|
51586
|
+
}
|
|
51587
|
+
for (let i = 1; i < effect.length; i++) {
|
|
51588
|
+
const arg = effect[i];
|
|
51589
|
+
if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
|
|
51590
|
+
else collectTraitRefsFromValue(arg, into);
|
|
51591
|
+
}
|
|
51592
|
+
}
|
|
51593
|
+
}
|
|
51594
|
+
function collectEmbeddedTraits(schema) {
|
|
51595
|
+
const out = /* @__PURE__ */ new Set();
|
|
51596
|
+
if (!schema?.orbitals) return out;
|
|
51597
|
+
for (const orbital of schema.orbitals) {
|
|
51598
|
+
if (!orbital || typeof orbital !== "object") continue;
|
|
51599
|
+
const traits2 = orbital.traits;
|
|
51600
|
+
if (!Array.isArray(traits2)) continue;
|
|
51601
|
+
for (const trait of traits2) {
|
|
51602
|
+
if (!trait || typeof trait !== "object") continue;
|
|
51603
|
+
const resolved = trait._resolved;
|
|
51604
|
+
const target = resolved && typeof resolved === "object" ? resolved : trait;
|
|
51605
|
+
const stateMachine = target.stateMachine;
|
|
51606
|
+
const transitions = stateMachine?.transitions;
|
|
51607
|
+
if (!Array.isArray(transitions)) continue;
|
|
51608
|
+
for (const t of transitions) {
|
|
51609
|
+
if (!t || typeof t !== "object") continue;
|
|
51610
|
+
const effects = t.effects;
|
|
51611
|
+
collectTraitRefsFromEffects(effects, out);
|
|
51612
|
+
}
|
|
51613
|
+
const initialEffects = target.initialEffects;
|
|
51614
|
+
collectTraitRefsFromEffects(initialEffects, out);
|
|
51615
|
+
const ticks2 = target.ticks;
|
|
51616
|
+
if (Array.isArray(ticks2)) {
|
|
51617
|
+
for (const tick of ticks2) {
|
|
51618
|
+
collectTraitRefsFromEffects(tick?.effects, out);
|
|
51619
|
+
}
|
|
51620
|
+
}
|
|
51621
|
+
}
|
|
51622
|
+
}
|
|
51623
|
+
return out;
|
|
51624
|
+
}
|
|
51625
|
+
|
|
51545
51626
|
// hooks/index.ts
|
|
51546
51627
|
init_useEventBus();
|
|
51547
51628
|
init_useUISlots();
|
|
@@ -52322,11 +52403,19 @@ function ServerBridgeProvider({
|
|
|
52322
52403
|
}
|
|
52323
52404
|
}
|
|
52324
52405
|
} else if (result.error) {
|
|
52325
|
-
|
|
52406
|
+
xOrbitalLog2.warn("response:fail", {
|
|
52407
|
+
orbital: orbitalName,
|
|
52408
|
+
event,
|
|
52409
|
+
error: result.error
|
|
52410
|
+
});
|
|
52326
52411
|
}
|
|
52327
52412
|
return { effects, meta };
|
|
52328
52413
|
} catch (err) {
|
|
52329
|
-
|
|
52414
|
+
xOrbitalLog2.error("response:network", {
|
|
52415
|
+
orbital: orbitalName,
|
|
52416
|
+
event,
|
|
52417
|
+
error: err instanceof Error ? err.message : String(err)
|
|
52418
|
+
});
|
|
52330
52419
|
return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
|
|
52331
52420
|
}
|
|
52332
52421
|
}, [connected, transport, eventBus]);
|
|
@@ -52516,32 +52605,49 @@ function SlotBridge() {
|
|
|
52516
52605
|
}, [slots, render, clear]);
|
|
52517
52606
|
return null;
|
|
52518
52607
|
}
|
|
52519
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
52608
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
52520
52609
|
for (const eff of effects) {
|
|
52521
52610
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
52522
52611
|
const patternRecord = eff.pattern;
|
|
52523
52612
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
52524
52613
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
52525
|
-
|
|
52526
|
-
|
|
52527
|
-
|
|
52528
|
-
|
|
52529
|
-
|
|
52530
|
-
|
|
52531
|
-
|
|
52532
|
-
|
|
52533
|
-
|
|
52534
|
-
|
|
52535
|
-
|
|
52536
|
-
}
|
|
52537
|
-
sourceTrait
|
|
52538
|
-
|
|
52614
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
52615
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
52616
|
+
const props = {
|
|
52617
|
+
...inlineProps,
|
|
52618
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
52619
|
+
};
|
|
52620
|
+
if (isEmbedded) {
|
|
52621
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
52622
|
+
sourceTrait,
|
|
52623
|
+
slot: eff.slot,
|
|
52624
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52625
|
+
});
|
|
52626
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
52627
|
+
pattern: patternType,
|
|
52628
|
+
props,
|
|
52629
|
+
priority: 0,
|
|
52630
|
+
animation: "fade"
|
|
52631
|
+
});
|
|
52632
|
+
} else {
|
|
52633
|
+
xOrbitalLog3.info("slot-write", {
|
|
52634
|
+
slot: eff.slot,
|
|
52635
|
+
sourceTrait,
|
|
52636
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52637
|
+
});
|
|
52638
|
+
uiSlots.render({
|
|
52639
|
+
target: eff.slot,
|
|
52640
|
+
pattern: patternType,
|
|
52641
|
+
props,
|
|
52642
|
+
sourceTrait
|
|
52643
|
+
});
|
|
52644
|
+
}
|
|
52539
52645
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
52540
52646
|
onNavigate(eff.route, eff.params);
|
|
52541
52647
|
}
|
|
52542
52648
|
}
|
|
52543
52649
|
}
|
|
52544
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
52650
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
52545
52651
|
const slotsActions = useSlotsActions();
|
|
52546
52652
|
const bridge = useServerBridge();
|
|
52547
52653
|
const uiSlots = useUISlots();
|
|
@@ -52557,9 +52663,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52557
52663
|
for (const name of targets) {
|
|
52558
52664
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
52559
52665
|
recordServerResponse(name, event, meta);
|
|
52560
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52666
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52561
52667
|
}
|
|
52562
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
52668
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
52563
52669
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
52564
52670
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
52565
52671
|
const initSentRef = React128.useRef(false);
|
|
@@ -52599,10 +52705,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52599
52705
|
effects: effectTraces,
|
|
52600
52706
|
timestamp: Date.now()
|
|
52601
52707
|
});
|
|
52602
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52708
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52603
52709
|
}
|
|
52604
52710
|
})();
|
|
52605
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
52711
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
52606
52712
|
return null;
|
|
52607
52713
|
}
|
|
52608
52714
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -52708,6 +52814,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52708
52814
|
}
|
|
52709
52815
|
return map;
|
|
52710
52816
|
}, [schema]);
|
|
52817
|
+
const embeddedTraits = React128.useMemo(() => {
|
|
52818
|
+
return collectEmbeddedTraits(schema);
|
|
52819
|
+
}, [schema]);
|
|
52711
52820
|
const inner = /* @__PURE__ */ jsxRuntime.jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52712
52821
|
EntitySchemaProvider,
|
|
52713
52822
|
{
|
|
@@ -52722,6 +52831,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52722
52831
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
52723
52832
|
traitConfigsByName,
|
|
52724
52833
|
orbitalsByTrait,
|
|
52834
|
+
embeddedTraits,
|
|
52725
52835
|
onNavigate,
|
|
52726
52836
|
onLocalFallback,
|
|
52727
52837
|
persistence
|
package/dist/avl/index.js
CHANGED
|
@@ -4446,6 +4446,16 @@ function useUISlotManager() {
|
|
|
4446
4446
|
},
|
|
4447
4447
|
[]
|
|
4448
4448
|
);
|
|
4449
|
+
const updateTraitContent = useCallback(
|
|
4450
|
+
(traitName, content) => {
|
|
4451
|
+
const id = generateId();
|
|
4452
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
4453
|
+
indexTraitRender(traitName, fullContent);
|
|
4454
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
4455
|
+
return id;
|
|
4456
|
+
},
|
|
4457
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
4458
|
+
);
|
|
4449
4459
|
return {
|
|
4450
4460
|
slots,
|
|
4451
4461
|
render,
|
|
@@ -4457,7 +4467,8 @@ function useUISlotManager() {
|
|
|
4457
4467
|
hasContent,
|
|
4458
4468
|
getContent,
|
|
4459
4469
|
getTraitContent,
|
|
4460
|
-
subscribeTrait
|
|
4470
|
+
subscribeTrait,
|
|
4471
|
+
updateTraitContent
|
|
4461
4472
|
};
|
|
4462
4473
|
}
|
|
4463
4474
|
var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
@@ -51496,6 +51507,76 @@ function useResolvedSchema(schema, pageName) {
|
|
|
51496
51507
|
return result;
|
|
51497
51508
|
}
|
|
51498
51509
|
|
|
51510
|
+
// runtime/embedded-traits.ts
|
|
51511
|
+
var TRAIT_BINDING_PREFIX = "@trait.";
|
|
51512
|
+
function collectTraitRefsFromValue(value, into) {
|
|
51513
|
+
if (value === null || value === void 0) return;
|
|
51514
|
+
if (typeof value === "string") {
|
|
51515
|
+
if (value.startsWith(TRAIT_BINDING_PREFIX)) {
|
|
51516
|
+
const rest = value.slice(TRAIT_BINDING_PREFIX.length);
|
|
51517
|
+
const dot = rest.indexOf(".");
|
|
51518
|
+
const traitName = dot === -1 ? rest : rest.slice(0, dot);
|
|
51519
|
+
if (traitName.length > 0) into.add(traitName);
|
|
51520
|
+
}
|
|
51521
|
+
return;
|
|
51522
|
+
}
|
|
51523
|
+
if (Array.isArray(value)) {
|
|
51524
|
+
for (const item of value) collectTraitRefsFromValue(item, into);
|
|
51525
|
+
return;
|
|
51526
|
+
}
|
|
51527
|
+
if (typeof value === "object") {
|
|
51528
|
+
for (const v of Object.values(value)) {
|
|
51529
|
+
collectTraitRefsFromValue(v, into);
|
|
51530
|
+
}
|
|
51531
|
+
}
|
|
51532
|
+
}
|
|
51533
|
+
function collectTraitRefsFromEffects(effects, into) {
|
|
51534
|
+
if (!effects) return;
|
|
51535
|
+
for (const effect of effects) {
|
|
51536
|
+
if (!Array.isArray(effect)) continue;
|
|
51537
|
+
if (effect[0] === "render-ui" && effect.length >= 3) {
|
|
51538
|
+
collectTraitRefsFromValue(effect[2], into);
|
|
51539
|
+
continue;
|
|
51540
|
+
}
|
|
51541
|
+
for (let i = 1; i < effect.length; i++) {
|
|
51542
|
+
const arg = effect[i];
|
|
51543
|
+
if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
|
|
51544
|
+
else collectTraitRefsFromValue(arg, into);
|
|
51545
|
+
}
|
|
51546
|
+
}
|
|
51547
|
+
}
|
|
51548
|
+
function collectEmbeddedTraits(schema) {
|
|
51549
|
+
const out = /* @__PURE__ */ new Set();
|
|
51550
|
+
if (!schema?.orbitals) return out;
|
|
51551
|
+
for (const orbital of schema.orbitals) {
|
|
51552
|
+
if (!orbital || typeof orbital !== "object") continue;
|
|
51553
|
+
const traits2 = orbital.traits;
|
|
51554
|
+
if (!Array.isArray(traits2)) continue;
|
|
51555
|
+
for (const trait of traits2) {
|
|
51556
|
+
if (!trait || typeof trait !== "object") continue;
|
|
51557
|
+
const resolved = trait._resolved;
|
|
51558
|
+
const target = resolved && typeof resolved === "object" ? resolved : trait;
|
|
51559
|
+
const stateMachine = target.stateMachine;
|
|
51560
|
+
const transitions = stateMachine?.transitions;
|
|
51561
|
+
if (!Array.isArray(transitions)) continue;
|
|
51562
|
+
for (const t of transitions) {
|
|
51563
|
+
if (!t || typeof t !== "object") continue;
|
|
51564
|
+
const effects = t.effects;
|
|
51565
|
+
collectTraitRefsFromEffects(effects, out);
|
|
51566
|
+
}
|
|
51567
|
+
const initialEffects = target.initialEffects;
|
|
51568
|
+
collectTraitRefsFromEffects(initialEffects, out);
|
|
51569
|
+
const ticks2 = target.ticks;
|
|
51570
|
+
if (Array.isArray(ticks2)) {
|
|
51571
|
+
for (const tick of ticks2) {
|
|
51572
|
+
collectTraitRefsFromEffects(tick?.effects, out);
|
|
51573
|
+
}
|
|
51574
|
+
}
|
|
51575
|
+
}
|
|
51576
|
+
}
|
|
51577
|
+
return out;
|
|
51578
|
+
}
|
|
51579
|
+
|
|
51499
51580
|
// hooks/index.ts
|
|
51500
51581
|
init_useEventBus();
|
|
51501
51582
|
init_useUISlots();
|
|
@@ -52276,11 +52357,19 @@ function ServerBridgeProvider({
|
|
|
52276
52357
|
}
|
|
52277
52358
|
}
|
|
52278
52359
|
} else if (result.error) {
|
|
52279
|
-
|
|
52360
|
+
xOrbitalLog2.warn("response:fail", {
|
|
52361
|
+
orbital: orbitalName,
|
|
52362
|
+
event,
|
|
52363
|
+
error: result.error
|
|
52364
|
+
});
|
|
52280
52365
|
}
|
|
52281
52366
|
return { effects, meta };
|
|
52282
52367
|
} catch (err) {
|
|
52283
|
-
|
|
52368
|
+
xOrbitalLog2.error("response:network", {
|
|
52369
|
+
orbital: orbitalName,
|
|
52370
|
+
event,
|
|
52371
|
+
error: err instanceof Error ? err.message : String(err)
|
|
52372
|
+
});
|
|
52284
52373
|
return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
|
|
52285
52374
|
}
|
|
52286
52375
|
}, [connected, transport, eventBus]);
|
|
@@ -52470,32 +52559,49 @@ function SlotBridge() {
|
|
|
52470
52559
|
}, [slots, render, clear]);
|
|
52471
52560
|
return null;
|
|
52472
52561
|
}
|
|
52473
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
52562
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
52474
52563
|
for (const eff of effects) {
|
|
52475
52564
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
52476
52565
|
const patternRecord = eff.pattern;
|
|
52477
52566
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
52478
52567
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
52479
|
-
|
|
52480
|
-
|
|
52481
|
-
|
|
52482
|
-
|
|
52483
|
-
|
|
52484
|
-
|
|
52485
|
-
|
|
52486
|
-
|
|
52487
|
-
|
|
52488
|
-
|
|
52489
|
-
|
|
52490
|
-
}
|
|
52491
|
-
sourceTrait
|
|
52492
|
-
|
|
52568
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
52569
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
52570
|
+
const props = {
|
|
52571
|
+
...inlineProps,
|
|
52572
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
52573
|
+
};
|
|
52574
|
+
if (isEmbedded) {
|
|
52575
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
52576
|
+
sourceTrait,
|
|
52577
|
+
slot: eff.slot,
|
|
52578
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52579
|
+
});
|
|
52580
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
52581
|
+
pattern: patternType,
|
|
52582
|
+
props,
|
|
52583
|
+
priority: 0,
|
|
52584
|
+
animation: "fade"
|
|
52585
|
+
});
|
|
52586
|
+
} else {
|
|
52587
|
+
xOrbitalLog3.info("slot-write", {
|
|
52588
|
+
slot: eff.slot,
|
|
52589
|
+
sourceTrait,
|
|
52590
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52591
|
+
});
|
|
52592
|
+
uiSlots.render({
|
|
52593
|
+
target: eff.slot,
|
|
52594
|
+
pattern: patternType,
|
|
52595
|
+
props,
|
|
52596
|
+
sourceTrait
|
|
52597
|
+
});
|
|
52598
|
+
}
|
|
52493
52599
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
52494
52600
|
onNavigate(eff.route, eff.params);
|
|
52495
52601
|
}
|
|
52496
52602
|
}
|
|
52497
52603
|
}
|
|
52498
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
52604
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
52499
52605
|
const slotsActions = useSlotsActions();
|
|
52500
52606
|
const bridge = useServerBridge();
|
|
52501
52607
|
const uiSlots = useUISlots();
|
|
@@ -52511,9 +52617,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52511
52617
|
for (const name of targets) {
|
|
52512
52618
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
52513
52619
|
recordServerResponse(name, event, meta);
|
|
52514
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52620
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52515
52621
|
}
|
|
52516
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
52622
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
52517
52623
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
52518
52624
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
52519
52625
|
const initSentRef = useRef(false);
|
|
@@ -52553,10 +52659,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52553
52659
|
effects: effectTraces,
|
|
52554
52660
|
timestamp: Date.now()
|
|
52555
52661
|
});
|
|
52556
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52662
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52557
52663
|
}
|
|
52558
52664
|
})();
|
|
52559
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
52665
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
52560
52666
|
return null;
|
|
52561
52667
|
}
|
|
52562
52668
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -52662,6 +52768,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52662
52768
|
}
|
|
52663
52769
|
return map;
|
|
52664
52770
|
}, [schema]);
|
|
52771
|
+
const embeddedTraits = useMemo(() => {
|
|
52772
|
+
return collectEmbeddedTraits(schema);
|
|
52773
|
+
}, [schema]);
|
|
52665
52774
|
const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
|
|
52666
52775
|
EntitySchemaProvider,
|
|
52667
52776
|
{
|
|
@@ -52676,6 +52785,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52676
52785
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
52677
52786
|
traitConfigsByName,
|
|
52678
52787
|
orbitalsByTrait,
|
|
52788
|
+
embeddedTraits,
|
|
52679
52789
|
onNavigate,
|
|
52680
52790
|
onLocalFallback,
|
|
52681
52791
|
persistence
|
|
@@ -41153,6 +41153,16 @@ function useUISlotManager() {
|
|
|
41153
41153
|
},
|
|
41154
41154
|
[]
|
|
41155
41155
|
);
|
|
41156
|
+
const updateTraitContent = React111.useCallback(
|
|
41157
|
+
(traitName, content) => {
|
|
41158
|
+
const id = generateId();
|
|
41159
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
41160
|
+
indexTraitRender(traitName, fullContent);
|
|
41161
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
41162
|
+
return id;
|
|
41163
|
+
},
|
|
41164
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
41165
|
+
);
|
|
41156
41166
|
return {
|
|
41157
41167
|
slots,
|
|
41158
41168
|
render,
|
|
@@ -41164,7 +41174,8 @@ function useUISlotManager() {
|
|
|
41164
41174
|
hasContent,
|
|
41165
41175
|
getContent,
|
|
41166
41176
|
getTraitContent,
|
|
41167
|
-
subscribeTrait
|
|
41177
|
+
subscribeTrait,
|
|
41178
|
+
updateTraitContent
|
|
41168
41179
|
};
|
|
41169
41180
|
}
|
|
41170
41181
|
|
package/dist/components/index.js
CHANGED
|
@@ -41108,6 +41108,16 @@ function useUISlotManager() {
|
|
|
41108
41108
|
},
|
|
41109
41109
|
[]
|
|
41110
41110
|
);
|
|
41111
|
+
const updateTraitContent = useCallback(
|
|
41112
|
+
(traitName, content) => {
|
|
41113
|
+
const id = generateId();
|
|
41114
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
41115
|
+
indexTraitRender(traitName, fullContent);
|
|
41116
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
41117
|
+
return id;
|
|
41118
|
+
},
|
|
41119
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
41120
|
+
);
|
|
41111
41121
|
return {
|
|
41112
41122
|
slots,
|
|
41113
41123
|
render,
|
|
@@ -41119,7 +41129,8 @@ function useUISlotManager() {
|
|
|
41119
41129
|
hasContent,
|
|
41120
41130
|
getContent,
|
|
41121
41131
|
getTraitContent,
|
|
41122
|
-
subscribeTrait
|
|
41132
|
+
subscribeTrait,
|
|
41133
|
+
updateTraitContent
|
|
41123
41134
|
};
|
|
41124
41135
|
}
|
|
41125
41136
|
|
package/dist/context/index.cjs
CHANGED
|
@@ -305,6 +305,16 @@ function useUISlotManager() {
|
|
|
305
305
|
},
|
|
306
306
|
[]
|
|
307
307
|
);
|
|
308
|
+
const updateTraitContent = react.useCallback(
|
|
309
|
+
(traitName, content) => {
|
|
310
|
+
const id = generateId();
|
|
311
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
312
|
+
indexTraitRender(traitName, fullContent);
|
|
313
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
314
|
+
return id;
|
|
315
|
+
},
|
|
316
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
317
|
+
);
|
|
308
318
|
return {
|
|
309
319
|
slots,
|
|
310
320
|
render,
|
|
@@ -316,7 +326,8 @@ function useUISlotManager() {
|
|
|
316
326
|
hasContent,
|
|
317
327
|
getContent,
|
|
318
328
|
getTraitContent,
|
|
319
|
-
subscribeTrait
|
|
329
|
+
subscribeTrait,
|
|
330
|
+
updateTraitContent
|
|
320
331
|
};
|
|
321
332
|
}
|
|
322
333
|
var UISlotContext = react.createContext(null);
|
package/dist/context/index.js
CHANGED
|
@@ -303,6 +303,16 @@ function useUISlotManager() {
|
|
|
303
303
|
},
|
|
304
304
|
[]
|
|
305
305
|
);
|
|
306
|
+
const updateTraitContent = useCallback(
|
|
307
|
+
(traitName, content) => {
|
|
308
|
+
const id = generateId();
|
|
309
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
310
|
+
indexTraitRender(traitName, fullContent);
|
|
311
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
312
|
+
return id;
|
|
313
|
+
},
|
|
314
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
315
|
+
);
|
|
306
316
|
return {
|
|
307
317
|
slots,
|
|
308
318
|
render,
|
|
@@ -314,7 +324,8 @@ function useUISlotManager() {
|
|
|
314
324
|
hasContent,
|
|
315
325
|
getContent,
|
|
316
326
|
getTraitContent,
|
|
317
|
-
subscribeTrait
|
|
327
|
+
subscribeTrait,
|
|
328
|
+
updateTraitContent
|
|
318
329
|
};
|
|
319
330
|
}
|
|
320
331
|
var UISlotContext = createContext(null);
|
package/dist/hooks/index.cjs
CHANGED
|
@@ -1348,6 +1348,16 @@ function useUISlotManager() {
|
|
|
1348
1348
|
},
|
|
1349
1349
|
[]
|
|
1350
1350
|
);
|
|
1351
|
+
const updateTraitContent = react.useCallback(
|
|
1352
|
+
(traitName, content) => {
|
|
1353
|
+
const id = generateId();
|
|
1354
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
1355
|
+
indexTraitRender(traitName, fullContent);
|
|
1356
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
1357
|
+
return id;
|
|
1358
|
+
},
|
|
1359
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
1360
|
+
);
|
|
1351
1361
|
return {
|
|
1352
1362
|
slots,
|
|
1353
1363
|
render,
|
|
@@ -1359,7 +1369,8 @@ function useUISlotManager() {
|
|
|
1359
1369
|
hasContent,
|
|
1360
1370
|
getContent,
|
|
1361
1371
|
getTraitContent,
|
|
1362
|
-
subscribeTrait
|
|
1372
|
+
subscribeTrait,
|
|
1373
|
+
updateTraitContent
|
|
1363
1374
|
};
|
|
1364
1375
|
}
|
|
1365
1376
|
var UI_PREFIX = "UI:";
|
package/dist/hooks/index.js
CHANGED
|
@@ -1346,6 +1346,16 @@ function useUISlotManager() {
|
|
|
1346
1346
|
},
|
|
1347
1347
|
[]
|
|
1348
1348
|
);
|
|
1349
|
+
const updateTraitContent = useCallback(
|
|
1350
|
+
(traitName, content) => {
|
|
1351
|
+
const id = generateId();
|
|
1352
|
+
const fullContent = { ...content, id, sourceTrait: traitName };
|
|
1353
|
+
indexTraitRender(traitName, fullContent);
|
|
1354
|
+
notifyTraitSubscribers(traitName, fullContent);
|
|
1355
|
+
return id;
|
|
1356
|
+
},
|
|
1357
|
+
[indexTraitRender, notifyTraitSubscribers]
|
|
1358
|
+
);
|
|
1349
1359
|
return {
|
|
1350
1360
|
slots,
|
|
1351
1361
|
render,
|
|
@@ -1357,7 +1367,8 @@ function useUISlotManager() {
|
|
|
1357
1367
|
hasContent,
|
|
1358
1368
|
getContent,
|
|
1359
1369
|
getTraitContent,
|
|
1360
|
-
subscribeTrait
|
|
1370
|
+
subscribeTrait,
|
|
1371
|
+
updateTraitContent
|
|
1361
1372
|
};
|
|
1362
1373
|
}
|
|
1363
1374
|
var UI_PREFIX = "UI:";
|
|
@@ -119,6 +119,20 @@ export interface UISlotManager {
|
|
|
119
119
|
* the trait they embed actually changes — not on every slot update.
|
|
120
120
|
*/
|
|
121
121
|
subscribeTrait: (traitName: string, callback: TraitChangeCallback) => () => void;
|
|
122
|
+
/**
|
|
123
|
+
* Update only the per-trait sidecar without writing to any slot.
|
|
124
|
+
*
|
|
125
|
+
* Used for embed-aware slot routing: when a trait is referenced via
|
|
126
|
+
* `@trait.X` by a sibling layout's render-ui, its render output should
|
|
127
|
+
* not stack into the same slot the layout writes — the layout owns the
|
|
128
|
+
* slot and embeds the trait's frame via `<TraitFrame>`. This method
|
|
129
|
+
* keeps the per-trait sidecar (`traitIndexRef`) up-to-date so
|
|
130
|
+
* `<TraitFrame>` re-renders, while leaving `slots[target]` untouched.
|
|
131
|
+
*
|
|
132
|
+
* Mirrors what the compiled-path codegen does structurally — atoms
|
|
133
|
+
* inlined as JSX inside the layout's pattern, not writing slots.
|
|
134
|
+
*/
|
|
135
|
+
updateTraitContent: (traitName: string, content: Omit<SlotContent, 'id' | 'sourceTrait'>) => string;
|
|
122
136
|
}
|
|
123
137
|
declare const DEFAULT_SLOTS: Record<UISlot, SlotContent | null>;
|
|
124
138
|
/**
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Embed-aware slot routing — static analysis pass.
|
|
3
|
+
*
|
|
4
|
+
* Walks every trait's `transitions[].effects` looking for `render-ui`
|
|
5
|
+
* patterns whose tree contains `@trait.<Name>` string literals. Returns
|
|
6
|
+
* the flat set of trait names that are referenced this way by some
|
|
7
|
+
* sibling layout.
|
|
8
|
+
*
|
|
9
|
+
* Used by `<OrbPreview>` to route `applyServerEffects` — when an
|
|
10
|
+
* embedded trait's render-ui effect arrives, the runtime updates that
|
|
11
|
+
* trait's per-trait sidecar (`traitIndexRef`) only and skips the slot
|
|
12
|
+
* write. The sibling layout owns the slot and embeds the trait's frame
|
|
13
|
+
* via `<TraitFrame>`. Mirrors the compiled-path codegen which inlines
|
|
14
|
+
* the atom views as JSX inside the layout's pattern, never having them
|
|
15
|
+
* write a shared slot.
|
|
16
|
+
*
|
|
17
|
+
* The walker is a structural twin of
|
|
18
|
+
* `packages/almadar-runtime/src/resolver/reference-resolver.ts`'s
|
|
19
|
+
* `renameEventsInRenderUiConfig` — same recursive pattern shape, just
|
|
20
|
+
* collecting `@trait.X` substrings instead of renaming events.
|
|
21
|
+
*
|
|
22
|
+
* @packageDocumentation
|
|
23
|
+
*/
|
|
24
|
+
import type { OrbitalSchema } from '@almadar/core';
|
|
25
|
+
/**
|
|
26
|
+
* Build the flat set of trait names that are referenced via `@trait.X`
|
|
27
|
+
* by at least one trait's render-ui in the resolved schema.
|
|
28
|
+
*
|
|
29
|
+
* Safe to call on the resolved (post-inline) schema. Memoize by
|
|
30
|
+
* reference at the call site.
|
|
31
|
+
*/
|
|
32
|
+
export declare function collectEmbeddedTraits(schema: OrbitalSchema | undefined | null): ReadonlySet<string>;
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -38974,6 +38974,78 @@ init_Box();
|
|
|
38974
38974
|
init_Typography();
|
|
38975
38975
|
init_UISlotRenderer();
|
|
38976
38976
|
init_useEventBus();
|
|
38977
|
+
|
|
38978
|
+
// runtime/embedded-traits.ts
|
|
38979
|
+
var TRAIT_BINDING_PREFIX = "@trait.";
|
|
38980
|
+
function collectTraitRefsFromValue(value, into) {
|
|
38981
|
+
if (value === null || value === void 0) return;
|
|
38982
|
+
if (typeof value === "string") {
|
|
38983
|
+
if (value.startsWith(TRAIT_BINDING_PREFIX)) {
|
|
38984
|
+
const rest = value.slice(TRAIT_BINDING_PREFIX.length);
|
|
38985
|
+
const dot = rest.indexOf(".");
|
|
38986
|
+
const traitName = dot === -1 ? rest : rest.slice(0, dot);
|
|
38987
|
+
if (traitName.length > 0) into.add(traitName);
|
|
38988
|
+
}
|
|
38989
|
+
return;
|
|
38990
|
+
}
|
|
38991
|
+
if (Array.isArray(value)) {
|
|
38992
|
+
for (const item of value) collectTraitRefsFromValue(item, into);
|
|
38993
|
+
return;
|
|
38994
|
+
}
|
|
38995
|
+
if (typeof value === "object") {
|
|
38996
|
+
for (const v of Object.values(value)) {
|
|
38997
|
+
collectTraitRefsFromValue(v, into);
|
|
38998
|
+
}
|
|
38999
|
+
}
|
|
39000
|
+
}
|
|
39001
|
+
function collectTraitRefsFromEffects(effects, into) {
|
|
39002
|
+
if (!effects) return;
|
|
39003
|
+
for (const effect of effects) {
|
|
39004
|
+
if (!Array.isArray(effect)) continue;
|
|
39005
|
+
if (effect[0] === "render-ui" && effect.length >= 3) {
|
|
39006
|
+
collectTraitRefsFromValue(effect[2], into);
|
|
39007
|
+
continue;
|
|
39008
|
+
}
|
|
39009
|
+
for (let i = 1; i < effect.length; i++) {
|
|
39010
|
+
const arg = effect[i];
|
|
39011
|
+
if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
|
|
39012
|
+
else collectTraitRefsFromValue(arg, into);
|
|
39013
|
+
}
|
|
39014
|
+
}
|
|
39015
|
+
}
|
|
39016
|
+
function collectEmbeddedTraits(schema) {
|
|
39017
|
+
const out = /* @__PURE__ */ new Set();
|
|
39018
|
+
if (!schema?.orbitals) return out;
|
|
39019
|
+
for (const orbital of schema.orbitals) {
|
|
39020
|
+
if (!orbital || typeof orbital !== "object") continue;
|
|
39021
|
+
const traits2 = orbital.traits;
|
|
39022
|
+
if (!Array.isArray(traits2)) continue;
|
|
39023
|
+
for (const trait of traits2) {
|
|
39024
|
+
if (!trait || typeof trait !== "object") continue;
|
|
39025
|
+
const resolved = trait._resolved;
|
|
39026
|
+
const target = resolved && typeof resolved === "object" ? resolved : trait;
|
|
39027
|
+
const stateMachine = target.stateMachine;
|
|
39028
|
+
const transitions = stateMachine?.transitions;
|
|
39029
|
+
if (!Array.isArray(transitions)) continue;
|
|
39030
|
+
for (const t of transitions) {
|
|
39031
|
+
if (!t || typeof t !== "object") continue;
|
|
39032
|
+
const effects = t.effects;
|
|
39033
|
+
collectTraitRefsFromEffects(effects, out);
|
|
39034
|
+
}
|
|
39035
|
+
const initialEffects = target.initialEffects;
|
|
39036
|
+
collectTraitRefsFromEffects(initialEffects, out);
|
|
39037
|
+
const ticks2 = target.ticks;
|
|
39038
|
+
if (Array.isArray(ticks2)) {
|
|
39039
|
+
for (const tick of ticks2) {
|
|
39040
|
+
collectTraitRefsFromEffects(tick?.effects, out);
|
|
39041
|
+
}
|
|
39042
|
+
}
|
|
39043
|
+
}
|
|
39044
|
+
}
|
|
39045
|
+
return out;
|
|
39046
|
+
}
|
|
39047
|
+
|
|
39048
|
+
// runtime/OrbPreview.tsx
|
|
38977
39049
|
init_SlotsContext();
|
|
38978
39050
|
init_EntitySchemaContext();
|
|
38979
39051
|
|
|
@@ -39103,11 +39175,19 @@ function ServerBridgeProvider({
|
|
|
39103
39175
|
}
|
|
39104
39176
|
}
|
|
39105
39177
|
} else if (result.error) {
|
|
39106
|
-
|
|
39178
|
+
xOrbitalLog2.warn("response:fail", {
|
|
39179
|
+
orbital: orbitalName,
|
|
39180
|
+
event,
|
|
39181
|
+
error: result.error
|
|
39182
|
+
});
|
|
39107
39183
|
}
|
|
39108
39184
|
return { effects, meta };
|
|
39109
39185
|
} catch (err) {
|
|
39110
|
-
|
|
39186
|
+
xOrbitalLog2.error("response:network", {
|
|
39187
|
+
orbital: orbitalName,
|
|
39188
|
+
event,
|
|
39189
|
+
error: err instanceof Error ? err.message : String(err)
|
|
39190
|
+
});
|
|
39111
39191
|
return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
|
|
39112
39192
|
}
|
|
39113
39193
|
}, [connected, transport, eventBus]);
|
|
@@ -39297,32 +39377,49 @@ function SlotBridge() {
|
|
|
39297
39377
|
}, [slots, render, clear]);
|
|
39298
39378
|
return null;
|
|
39299
39379
|
}
|
|
39300
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
39380
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
39301
39381
|
for (const eff of effects) {
|
|
39302
39382
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
39303
39383
|
const patternRecord = eff.pattern;
|
|
39304
39384
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
39305
39385
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
39306
|
-
|
|
39307
|
-
|
|
39308
|
-
|
|
39309
|
-
|
|
39310
|
-
|
|
39311
|
-
|
|
39312
|
-
|
|
39313
|
-
|
|
39314
|
-
|
|
39315
|
-
|
|
39316
|
-
|
|
39317
|
-
}
|
|
39318
|
-
sourceTrait
|
|
39319
|
-
|
|
39386
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
39387
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
39388
|
+
const props = {
|
|
39389
|
+
...inlineProps,
|
|
39390
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
39391
|
+
};
|
|
39392
|
+
if (isEmbedded) {
|
|
39393
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
39394
|
+
sourceTrait,
|
|
39395
|
+
slot: eff.slot,
|
|
39396
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39397
|
+
});
|
|
39398
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
39399
|
+
pattern: patternType,
|
|
39400
|
+
props,
|
|
39401
|
+
priority: 0,
|
|
39402
|
+
animation: "fade"
|
|
39403
|
+
});
|
|
39404
|
+
} else {
|
|
39405
|
+
xOrbitalLog3.info("slot-write", {
|
|
39406
|
+
slot: eff.slot,
|
|
39407
|
+
sourceTrait,
|
|
39408
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39409
|
+
});
|
|
39410
|
+
uiSlots.render({
|
|
39411
|
+
target: eff.slot,
|
|
39412
|
+
pattern: patternType,
|
|
39413
|
+
props,
|
|
39414
|
+
sourceTrait
|
|
39415
|
+
});
|
|
39416
|
+
}
|
|
39320
39417
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
39321
39418
|
onNavigate(eff.route, eff.params);
|
|
39322
39419
|
}
|
|
39323
39420
|
}
|
|
39324
39421
|
}
|
|
39325
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
39422
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
39326
39423
|
const slotsActions = useSlotsActions();
|
|
39327
39424
|
const bridge = useServerBridge();
|
|
39328
39425
|
const uiSlots = context.useUISlots();
|
|
@@ -39338,9 +39435,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39338
39435
|
for (const name of targets) {
|
|
39339
39436
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
39340
39437
|
recordServerResponse(name, event, meta);
|
|
39341
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39438
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39342
39439
|
}
|
|
39343
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
39440
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
39344
39441
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
39345
39442
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
39346
39443
|
const initSentRef = React115.useRef(false);
|
|
@@ -39380,10 +39477,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39380
39477
|
effects: effectTraces,
|
|
39381
39478
|
timestamp: Date.now()
|
|
39382
39479
|
});
|
|
39383
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39480
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39384
39481
|
}
|
|
39385
39482
|
})();
|
|
39386
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
39483
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
39387
39484
|
return null;
|
|
39388
39485
|
}
|
|
39389
39486
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -39489,6 +39586,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39489
39586
|
}
|
|
39490
39587
|
return map;
|
|
39491
39588
|
}, [schema]);
|
|
39589
|
+
const embeddedTraits = React115.useMemo(() => {
|
|
39590
|
+
return collectEmbeddedTraits(schema);
|
|
39591
|
+
}, [schema]);
|
|
39492
39592
|
const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39493
39593
|
EntitySchemaProvider,
|
|
39494
39594
|
{
|
|
@@ -39503,6 +39603,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39503
39603
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
39504
39604
|
traitConfigsByName,
|
|
39505
39605
|
orbitalsByTrait,
|
|
39606
|
+
embeddedTraits,
|
|
39506
39607
|
onNavigate,
|
|
39507
39608
|
onLocalFallback,
|
|
39508
39609
|
persistence
|
package/dist/runtime/index.js
CHANGED
|
@@ -38929,6 +38929,78 @@ init_Box();
|
|
|
38929
38929
|
init_Typography();
|
|
38930
38930
|
init_UISlotRenderer();
|
|
38931
38931
|
init_useEventBus();
|
|
38932
|
+
|
|
38933
|
+
// runtime/embedded-traits.ts
|
|
38934
|
+
var TRAIT_BINDING_PREFIX = "@trait.";
|
|
38935
|
+
function collectTraitRefsFromValue(value, into) {
|
|
38936
|
+
if (value === null || value === void 0) return;
|
|
38937
|
+
if (typeof value === "string") {
|
|
38938
|
+
if (value.startsWith(TRAIT_BINDING_PREFIX)) {
|
|
38939
|
+
const rest = value.slice(TRAIT_BINDING_PREFIX.length);
|
|
38940
|
+
const dot = rest.indexOf(".");
|
|
38941
|
+
const traitName = dot === -1 ? rest : rest.slice(0, dot);
|
|
38942
|
+
if (traitName.length > 0) into.add(traitName);
|
|
38943
|
+
}
|
|
38944
|
+
return;
|
|
38945
|
+
}
|
|
38946
|
+
if (Array.isArray(value)) {
|
|
38947
|
+
for (const item of value) collectTraitRefsFromValue(item, into);
|
|
38948
|
+
return;
|
|
38949
|
+
}
|
|
38950
|
+
if (typeof value === "object") {
|
|
38951
|
+
for (const v of Object.values(value)) {
|
|
38952
|
+
collectTraitRefsFromValue(v, into);
|
|
38953
|
+
}
|
|
38954
|
+
}
|
|
38955
|
+
}
|
|
38956
|
+
function collectTraitRefsFromEffects(effects, into) {
|
|
38957
|
+
if (!effects) return;
|
|
38958
|
+
for (const effect of effects) {
|
|
38959
|
+
if (!Array.isArray(effect)) continue;
|
|
38960
|
+
if (effect[0] === "render-ui" && effect.length >= 3) {
|
|
38961
|
+
collectTraitRefsFromValue(effect[2], into);
|
|
38962
|
+
continue;
|
|
38963
|
+
}
|
|
38964
|
+
for (let i = 1; i < effect.length; i++) {
|
|
38965
|
+
const arg = effect[i];
|
|
38966
|
+
if (Array.isArray(arg)) collectTraitRefsFromEffects([arg], into);
|
|
38967
|
+
else collectTraitRefsFromValue(arg, into);
|
|
38968
|
+
}
|
|
38969
|
+
}
|
|
38970
|
+
}
|
|
38971
|
+
function collectEmbeddedTraits(schema) {
|
|
38972
|
+
const out = /* @__PURE__ */ new Set();
|
|
38973
|
+
if (!schema?.orbitals) return out;
|
|
38974
|
+
for (const orbital of schema.orbitals) {
|
|
38975
|
+
if (!orbital || typeof orbital !== "object") continue;
|
|
38976
|
+
const traits2 = orbital.traits;
|
|
38977
|
+
if (!Array.isArray(traits2)) continue;
|
|
38978
|
+
for (const trait of traits2) {
|
|
38979
|
+
if (!trait || typeof trait !== "object") continue;
|
|
38980
|
+
const resolved = trait._resolved;
|
|
38981
|
+
const target = resolved && typeof resolved === "object" ? resolved : trait;
|
|
38982
|
+
const stateMachine = target.stateMachine;
|
|
38983
|
+
const transitions = stateMachine?.transitions;
|
|
38984
|
+
if (!Array.isArray(transitions)) continue;
|
|
38985
|
+
for (const t of transitions) {
|
|
38986
|
+
if (!t || typeof t !== "object") continue;
|
|
38987
|
+
const effects = t.effects;
|
|
38988
|
+
collectTraitRefsFromEffects(effects, out);
|
|
38989
|
+
}
|
|
38990
|
+
const initialEffects = target.initialEffects;
|
|
38991
|
+
collectTraitRefsFromEffects(initialEffects, out);
|
|
38992
|
+
const ticks2 = target.ticks;
|
|
38993
|
+
if (Array.isArray(ticks2)) {
|
|
38994
|
+
for (const tick of ticks2) {
|
|
38995
|
+
collectTraitRefsFromEffects(tick?.effects, out);
|
|
38996
|
+
}
|
|
38997
|
+
}
|
|
38998
|
+
}
|
|
38999
|
+
}
|
|
39000
|
+
return out;
|
|
39001
|
+
}
|
|
39002
|
+
|
|
39003
|
+
// runtime/OrbPreview.tsx
|
|
38932
39004
|
init_SlotsContext();
|
|
38933
39005
|
init_EntitySchemaContext();
|
|
38934
39006
|
|
|
@@ -39058,11 +39130,19 @@ function ServerBridgeProvider({
|
|
|
39058
39130
|
}
|
|
39059
39131
|
}
|
|
39060
39132
|
} else if (result.error) {
|
|
39061
|
-
|
|
39133
|
+
xOrbitalLog2.warn("response:fail", {
|
|
39134
|
+
orbital: orbitalName,
|
|
39135
|
+
event,
|
|
39136
|
+
error: result.error
|
|
39137
|
+
});
|
|
39062
39138
|
}
|
|
39063
39139
|
return { effects, meta };
|
|
39064
39140
|
} catch (err) {
|
|
39065
|
-
|
|
39141
|
+
xOrbitalLog2.error("response:network", {
|
|
39142
|
+
orbital: orbitalName,
|
|
39143
|
+
event,
|
|
39144
|
+
error: err instanceof Error ? err.message : String(err)
|
|
39145
|
+
});
|
|
39066
39146
|
return { effects: [], meta: { ...emptyMeta, error: err instanceof Error ? err.message : String(err) } };
|
|
39067
39147
|
}
|
|
39068
39148
|
}, [connected, transport, eventBus]);
|
|
@@ -39252,32 +39332,49 @@ function SlotBridge() {
|
|
|
39252
39332
|
}, [slots, render, clear]);
|
|
39253
39333
|
return null;
|
|
39254
39334
|
}
|
|
39255
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
39335
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
39256
39336
|
for (const eff of effects) {
|
|
39257
39337
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
39258
39338
|
const patternRecord = eff.pattern;
|
|
39259
39339
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
39260
39340
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
39261
|
-
|
|
39262
|
-
|
|
39263
|
-
|
|
39264
|
-
|
|
39265
|
-
|
|
39266
|
-
|
|
39267
|
-
|
|
39268
|
-
|
|
39269
|
-
|
|
39270
|
-
|
|
39271
|
-
|
|
39272
|
-
}
|
|
39273
|
-
sourceTrait
|
|
39274
|
-
|
|
39341
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
39342
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
39343
|
+
const props = {
|
|
39344
|
+
...inlineProps,
|
|
39345
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
39346
|
+
};
|
|
39347
|
+
if (isEmbedded) {
|
|
39348
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
39349
|
+
sourceTrait,
|
|
39350
|
+
slot: eff.slot,
|
|
39351
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39352
|
+
});
|
|
39353
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
39354
|
+
pattern: patternType,
|
|
39355
|
+
props,
|
|
39356
|
+
priority: 0,
|
|
39357
|
+
animation: "fade"
|
|
39358
|
+
});
|
|
39359
|
+
} else {
|
|
39360
|
+
xOrbitalLog3.info("slot-write", {
|
|
39361
|
+
slot: eff.slot,
|
|
39362
|
+
sourceTrait,
|
|
39363
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39364
|
+
});
|
|
39365
|
+
uiSlots.render({
|
|
39366
|
+
target: eff.slot,
|
|
39367
|
+
pattern: patternType,
|
|
39368
|
+
props,
|
|
39369
|
+
sourceTrait
|
|
39370
|
+
});
|
|
39371
|
+
}
|
|
39275
39372
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
39276
39373
|
onNavigate(eff.route, eff.params);
|
|
39277
39374
|
}
|
|
39278
39375
|
}
|
|
39279
39376
|
}
|
|
39280
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
39377
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
39281
39378
|
const slotsActions = useSlotsActions();
|
|
39282
39379
|
const bridge = useServerBridge();
|
|
39283
39380
|
const uiSlots = useUISlots();
|
|
@@ -39293,9 +39390,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39293
39390
|
for (const name of targets) {
|
|
39294
39391
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
39295
39392
|
recordServerResponse(name, event, meta);
|
|
39296
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39393
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39297
39394
|
}
|
|
39298
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
39395
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
39299
39396
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
39300
39397
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
39301
39398
|
const initSentRef = useRef(false);
|
|
@@ -39335,10 +39432,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39335
39432
|
effects: effectTraces,
|
|
39336
39433
|
timestamp: Date.now()
|
|
39337
39434
|
});
|
|
39338
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39435
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39339
39436
|
}
|
|
39340
39437
|
})();
|
|
39341
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
39438
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
39342
39439
|
return null;
|
|
39343
39440
|
}
|
|
39344
39441
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -39444,6 +39541,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39444
39541
|
}
|
|
39445
39542
|
return map;
|
|
39446
39543
|
}, [schema]);
|
|
39544
|
+
const embeddedTraits = useMemo(() => {
|
|
39545
|
+
return collectEmbeddedTraits(schema);
|
|
39546
|
+
}, [schema]);
|
|
39447
39547
|
const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
|
|
39448
39548
|
EntitySchemaProvider,
|
|
39449
39549
|
{
|
|
@@ -39458,6 +39558,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39458
39558
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
39459
39559
|
traitConfigsByName,
|
|
39460
39560
|
orbitalsByTrait,
|
|
39561
|
+
embeddedTraits,
|
|
39461
39562
|
onNavigate,
|
|
39462
39563
|
onLocalFallback,
|
|
39463
39564
|
persistence
|