@almadar/ui 4.11.0 → 4.12.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/dist/avl/index.cjs +123 -21
- package/dist/avl/index.js +123 -21
- 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 +113 -20
- package/dist/runtime/index.js +113 -20
- 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();
|
|
@@ -52516,32 +52597,49 @@ function SlotBridge() {
|
|
|
52516
52597
|
}, [slots, render, clear]);
|
|
52517
52598
|
return null;
|
|
52518
52599
|
}
|
|
52519
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
52600
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
52520
52601
|
for (const eff of effects) {
|
|
52521
52602
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
52522
52603
|
const patternRecord = eff.pattern;
|
|
52523
52604
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
52524
52605
|
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
|
-
|
|
52606
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
52607
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
52608
|
+
const props = {
|
|
52609
|
+
...inlineProps,
|
|
52610
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
52611
|
+
};
|
|
52612
|
+
if (isEmbedded) {
|
|
52613
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
52614
|
+
sourceTrait,
|
|
52615
|
+
slot: eff.slot,
|
|
52616
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52617
|
+
});
|
|
52618
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
52619
|
+
pattern: patternType,
|
|
52620
|
+
props,
|
|
52621
|
+
priority: 0,
|
|
52622
|
+
animation: "fade"
|
|
52623
|
+
});
|
|
52624
|
+
} else {
|
|
52625
|
+
xOrbitalLog3.info("slot-write", {
|
|
52626
|
+
slot: eff.slot,
|
|
52627
|
+
sourceTrait,
|
|
52628
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52629
|
+
});
|
|
52630
|
+
uiSlots.render({
|
|
52631
|
+
target: eff.slot,
|
|
52632
|
+
pattern: patternType,
|
|
52633
|
+
props,
|
|
52634
|
+
sourceTrait
|
|
52635
|
+
});
|
|
52636
|
+
}
|
|
52539
52637
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
52540
52638
|
onNavigate(eff.route, eff.params);
|
|
52541
52639
|
}
|
|
52542
52640
|
}
|
|
52543
52641
|
}
|
|
52544
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
52642
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
52545
52643
|
const slotsActions = useSlotsActions();
|
|
52546
52644
|
const bridge = useServerBridge();
|
|
52547
52645
|
const uiSlots = useUISlots();
|
|
@@ -52557,9 +52655,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52557
52655
|
for (const name of targets) {
|
|
52558
52656
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
52559
52657
|
recordServerResponse(name, event, meta);
|
|
52560
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52658
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52561
52659
|
}
|
|
52562
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
52660
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
52563
52661
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
52564
52662
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
52565
52663
|
const initSentRef = React128.useRef(false);
|
|
@@ -52599,10 +52697,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52599
52697
|
effects: effectTraces,
|
|
52600
52698
|
timestamp: Date.now()
|
|
52601
52699
|
});
|
|
52602
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52700
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52603
52701
|
}
|
|
52604
52702
|
})();
|
|
52605
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
52703
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
52606
52704
|
return null;
|
|
52607
52705
|
}
|
|
52608
52706
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -52708,6 +52806,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52708
52806
|
}
|
|
52709
52807
|
return map;
|
|
52710
52808
|
}, [schema]);
|
|
52809
|
+
const embeddedTraits = React128.useMemo(() => {
|
|
52810
|
+
return collectEmbeddedTraits(schema);
|
|
52811
|
+
}, [schema]);
|
|
52711
52812
|
const inner = /* @__PURE__ */ jsxRuntime.jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
52712
52813
|
EntitySchemaProvider,
|
|
52713
52814
|
{
|
|
@@ -52722,6 +52823,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52722
52823
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
52723
52824
|
traitConfigsByName,
|
|
52724
52825
|
orbitalsByTrait,
|
|
52826
|
+
embeddedTraits,
|
|
52725
52827
|
onNavigate,
|
|
52726
52828
|
onLocalFallback,
|
|
52727
52829
|
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();
|
|
@@ -52470,32 +52551,49 @@ function SlotBridge() {
|
|
|
52470
52551
|
}, [slots, render, clear]);
|
|
52471
52552
|
return null;
|
|
52472
52553
|
}
|
|
52473
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
52554
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
52474
52555
|
for (const eff of effects) {
|
|
52475
52556
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
52476
52557
|
const patternRecord = eff.pattern;
|
|
52477
52558
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
52478
52559
|
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
|
-
|
|
52560
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
52561
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
52562
|
+
const props = {
|
|
52563
|
+
...inlineProps,
|
|
52564
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
52565
|
+
};
|
|
52566
|
+
if (isEmbedded) {
|
|
52567
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
52568
|
+
sourceTrait,
|
|
52569
|
+
slot: eff.slot,
|
|
52570
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52571
|
+
});
|
|
52572
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
52573
|
+
pattern: patternType,
|
|
52574
|
+
props,
|
|
52575
|
+
priority: 0,
|
|
52576
|
+
animation: "fade"
|
|
52577
|
+
});
|
|
52578
|
+
} else {
|
|
52579
|
+
xOrbitalLog3.info("slot-write", {
|
|
52580
|
+
slot: eff.slot,
|
|
52581
|
+
sourceTrait,
|
|
52582
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
52583
|
+
});
|
|
52584
|
+
uiSlots.render({
|
|
52585
|
+
target: eff.slot,
|
|
52586
|
+
pattern: patternType,
|
|
52587
|
+
props,
|
|
52588
|
+
sourceTrait
|
|
52589
|
+
});
|
|
52590
|
+
}
|
|
52493
52591
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
52494
52592
|
onNavigate(eff.route, eff.params);
|
|
52495
52593
|
}
|
|
52496
52594
|
}
|
|
52497
52595
|
}
|
|
52498
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
52596
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
52499
52597
|
const slotsActions = useSlotsActions();
|
|
52500
52598
|
const bridge = useServerBridge();
|
|
52501
52599
|
const uiSlots = useUISlots();
|
|
@@ -52511,9 +52609,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52511
52609
|
for (const name of targets) {
|
|
52512
52610
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
52513
52611
|
recordServerResponse(name, event, meta);
|
|
52514
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52612
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52515
52613
|
}
|
|
52516
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
52614
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
52517
52615
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
52518
52616
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
52519
52617
|
const initSentRef = useRef(false);
|
|
@@ -52553,10 +52651,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
52553
52651
|
effects: effectTraces,
|
|
52554
52652
|
timestamp: Date.now()
|
|
52555
52653
|
});
|
|
52556
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
52654
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
52557
52655
|
}
|
|
52558
52656
|
})();
|
|
52559
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
52657
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
52560
52658
|
return null;
|
|
52561
52659
|
}
|
|
52562
52660
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -52662,6 +52760,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52662
52760
|
}
|
|
52663
52761
|
return map;
|
|
52664
52762
|
}, [schema]);
|
|
52763
|
+
const embeddedTraits = useMemo(() => {
|
|
52764
|
+
return collectEmbeddedTraits(schema);
|
|
52765
|
+
}, [schema]);
|
|
52665
52766
|
const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
|
|
52666
52767
|
EntitySchemaProvider,
|
|
52667
52768
|
{
|
|
@@ -52676,6 +52777,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
52676
52777
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
52677
52778
|
traitConfigsByName,
|
|
52678
52779
|
orbitalsByTrait,
|
|
52780
|
+
embeddedTraits,
|
|
52679
52781
|
onNavigate,
|
|
52680
52782
|
onLocalFallback,
|
|
52681
52783
|
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
|
|
|
@@ -39297,32 +39369,49 @@ function SlotBridge() {
|
|
|
39297
39369
|
}, [slots, render, clear]);
|
|
39298
39370
|
return null;
|
|
39299
39371
|
}
|
|
39300
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
39372
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
39301
39373
|
for (const eff of effects) {
|
|
39302
39374
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
39303
39375
|
const patternRecord = eff.pattern;
|
|
39304
39376
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
39305
39377
|
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
|
-
|
|
39378
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
39379
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
39380
|
+
const props = {
|
|
39381
|
+
...inlineProps,
|
|
39382
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
39383
|
+
};
|
|
39384
|
+
if (isEmbedded) {
|
|
39385
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
39386
|
+
sourceTrait,
|
|
39387
|
+
slot: eff.slot,
|
|
39388
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39389
|
+
});
|
|
39390
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
39391
|
+
pattern: patternType,
|
|
39392
|
+
props,
|
|
39393
|
+
priority: 0,
|
|
39394
|
+
animation: "fade"
|
|
39395
|
+
});
|
|
39396
|
+
} else {
|
|
39397
|
+
xOrbitalLog3.info("slot-write", {
|
|
39398
|
+
slot: eff.slot,
|
|
39399
|
+
sourceTrait,
|
|
39400
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39401
|
+
});
|
|
39402
|
+
uiSlots.render({
|
|
39403
|
+
target: eff.slot,
|
|
39404
|
+
pattern: patternType,
|
|
39405
|
+
props,
|
|
39406
|
+
sourceTrait
|
|
39407
|
+
});
|
|
39408
|
+
}
|
|
39320
39409
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
39321
39410
|
onNavigate(eff.route, eff.params);
|
|
39322
39411
|
}
|
|
39323
39412
|
}
|
|
39324
39413
|
}
|
|
39325
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
39414
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
39326
39415
|
const slotsActions = useSlotsActions();
|
|
39327
39416
|
const bridge = useServerBridge();
|
|
39328
39417
|
const uiSlots = context.useUISlots();
|
|
@@ -39338,9 +39427,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39338
39427
|
for (const name of targets) {
|
|
39339
39428
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
39340
39429
|
recordServerResponse(name, event, meta);
|
|
39341
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39430
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39342
39431
|
}
|
|
39343
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
39432
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
39344
39433
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
39345
39434
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
39346
39435
|
const initSentRef = React115.useRef(false);
|
|
@@ -39380,10 +39469,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39380
39469
|
effects: effectTraces,
|
|
39381
39470
|
timestamp: Date.now()
|
|
39382
39471
|
});
|
|
39383
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39472
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39384
39473
|
}
|
|
39385
39474
|
})();
|
|
39386
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
39475
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
39387
39476
|
return null;
|
|
39388
39477
|
}
|
|
39389
39478
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -39489,6 +39578,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39489
39578
|
}
|
|
39490
39579
|
return map;
|
|
39491
39580
|
}, [schema]);
|
|
39581
|
+
const embeddedTraits = React115.useMemo(() => {
|
|
39582
|
+
return collectEmbeddedTraits(schema);
|
|
39583
|
+
}, [schema]);
|
|
39492
39584
|
const inner = /* @__PURE__ */ jsxRuntime.jsx(providers.VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39493
39585
|
EntitySchemaProvider,
|
|
39494
39586
|
{
|
|
@@ -39503,6 +39595,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39503
39595
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
39504
39596
|
traitConfigsByName,
|
|
39505
39597
|
orbitalsByTrait,
|
|
39598
|
+
embeddedTraits,
|
|
39506
39599
|
onNavigate,
|
|
39507
39600
|
onLocalFallback,
|
|
39508
39601
|
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
|
|
|
@@ -39252,32 +39324,49 @@ function SlotBridge() {
|
|
|
39252
39324
|
}, [slots, render, clear]);
|
|
39253
39325
|
return null;
|
|
39254
39326
|
}
|
|
39255
|
-
function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
39327
|
+
function applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits) {
|
|
39256
39328
|
for (const eff of effects) {
|
|
39257
39329
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
39258
39330
|
const patternRecord = eff.pattern;
|
|
39259
39331
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
39260
39332
|
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
|
-
|
|
39333
|
+
const sourceTrait = eff.traitName ?? "server";
|
|
39334
|
+
const isEmbedded = embeddedTraits?.has(sourceTrait) ?? false;
|
|
39335
|
+
const props = {
|
|
39336
|
+
...inlineProps,
|
|
39337
|
+
...normalizedChildren !== void 0 ? { children: normalizedChildren } : {}
|
|
39338
|
+
};
|
|
39339
|
+
if (isEmbedded) {
|
|
39340
|
+
xOrbitalLog3.info("slot:embed-routed", {
|
|
39341
|
+
sourceTrait,
|
|
39342
|
+
slot: eff.slot,
|
|
39343
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39344
|
+
});
|
|
39345
|
+
uiSlots.updateTraitContent(sourceTrait, {
|
|
39346
|
+
pattern: patternType,
|
|
39347
|
+
props,
|
|
39348
|
+
priority: 0,
|
|
39349
|
+
animation: "fade"
|
|
39350
|
+
});
|
|
39351
|
+
} else {
|
|
39352
|
+
xOrbitalLog3.info("slot-write", {
|
|
39353
|
+
slot: eff.slot,
|
|
39354
|
+
sourceTrait,
|
|
39355
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39356
|
+
});
|
|
39357
|
+
uiSlots.render({
|
|
39358
|
+
target: eff.slot,
|
|
39359
|
+
pattern: patternType,
|
|
39360
|
+
props,
|
|
39361
|
+
sourceTrait
|
|
39362
|
+
});
|
|
39363
|
+
}
|
|
39275
39364
|
} else if (eff.type === "navigate" && eff.route && onNavigate) {
|
|
39276
39365
|
onNavigate(eff.route, eff.params);
|
|
39277
39366
|
}
|
|
39278
39367
|
}
|
|
39279
39368
|
}
|
|
39280
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
39369
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits }) {
|
|
39281
39370
|
const slotsActions = useSlotsActions();
|
|
39282
39371
|
const bridge = useServerBridge();
|
|
39283
39372
|
const uiSlots = useUISlots();
|
|
@@ -39293,9 +39382,9 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39293
39382
|
for (const name of targets) {
|
|
39294
39383
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
39295
39384
|
recordServerResponse(name, event, meta);
|
|
39296
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39385
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39297
39386
|
}
|
|
39298
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
39387
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, embeddedTraits]);
|
|
39299
39388
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
39300
39389
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
39301
39390
|
const initSentRef = useRef(false);
|
|
@@ -39335,10 +39424,10 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
39335
39424
|
effects: effectTraces,
|
|
39336
39425
|
timestamp: Date.now()
|
|
39337
39426
|
});
|
|
39338
|
-
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39427
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits);
|
|
39339
39428
|
}
|
|
39340
39429
|
})();
|
|
39341
|
-
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate]);
|
|
39430
|
+
}, [bridge.connected, orbitalNames, bridge.sendEvent, uiSlots, onNavigate, embeddedTraits]);
|
|
39342
39431
|
return null;
|
|
39343
39432
|
}
|
|
39344
39433
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
@@ -39444,6 +39533,9 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39444
39533
|
}
|
|
39445
39534
|
return map;
|
|
39446
39535
|
}, [schema]);
|
|
39536
|
+
const embeddedTraits = useMemo(() => {
|
|
39537
|
+
return collectEmbeddedTraits(schema);
|
|
39538
|
+
}, [schema]);
|
|
39447
39539
|
const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(
|
|
39448
39540
|
EntitySchemaProvider,
|
|
39449
39541
|
{
|
|
@@ -39458,6 +39550,7 @@ function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavi
|
|
|
39458
39550
|
orbitalNames: serverUrl || transport ? pageOrbitalNames : void 0,
|
|
39459
39551
|
traitConfigsByName,
|
|
39460
39552
|
orbitalsByTrait,
|
|
39553
|
+
embeddedTraits,
|
|
39461
39554
|
onNavigate,
|
|
39462
39555
|
onLocalFallback,
|
|
39463
39556
|
persistence
|