@almadar/ui 4.6.13 → 4.7.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 +160 -62
- package/dist/avl/index.js +160 -62
- package/dist/components/atoms/Card.d.ts +2 -0
- package/dist/components/index.cjs +36 -64
- package/dist/components/index.js +37 -65
- package/dist/docs/index.d.cts +2 -0
- package/dist/hooks/index.cjs +33 -62
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +34 -63
- package/dist/hooks/useUIEvents.d.ts +31 -26
- package/dist/lib/index.cjs +3 -3
- package/dist/lib/index.js +3 -3
- package/dist/marketing/index.d.cts +2 -0
- package/dist/providers/index.cjs +4 -3
- package/dist/providers/index.js +4 -3
- package/dist/runtime/OrbPreview.d.ts +9 -1
- package/dist/runtime/index.cjs +157 -59
- package/dist/runtime/index.js +157 -59
- package/dist/runtime/useTraitStateMachine.d.ts +21 -2
- package/package.json +2 -2
package/dist/runtime/index.js
CHANGED
|
@@ -1071,13 +1071,23 @@ function SlotsProvider({ children }) {
|
|
|
1071
1071
|
const setSlotPatterns = useCallback((slot, patterns, source) => {
|
|
1072
1072
|
const sourceKey = source?.trait ?? DEFAULT_SOURCE_KEY;
|
|
1073
1073
|
const entityProp = patterns[0]?.pattern && typeof patterns[0].pattern === "object" ? patterns[0].pattern.entity : void 0;
|
|
1074
|
+
const firstPatternType = patterns[0]?.pattern && typeof patterns[0].pattern === "object" ? patterns[0].pattern.type : void 0;
|
|
1074
1075
|
slotLog.debug("setSlotPatterns", {
|
|
1075
1076
|
slot,
|
|
1076
1077
|
sourceKey,
|
|
1077
1078
|
patternCount: patterns.length,
|
|
1078
|
-
firstPatternType
|
|
1079
|
+
firstPatternType,
|
|
1079
1080
|
entityRefId: refId(entityProp)
|
|
1080
1081
|
});
|
|
1082
|
+
if (source?.trait) {
|
|
1083
|
+
xOrbitalLog.info("slot-set", {
|
|
1084
|
+
slot,
|
|
1085
|
+
sourceTrait: source.trait,
|
|
1086
|
+
patternCount: patterns.length,
|
|
1087
|
+
firstPatternType,
|
|
1088
|
+
state: source.state
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1081
1091
|
setSlots((prev) => {
|
|
1082
1092
|
const prevSlot = prev[slot] ?? {};
|
|
1083
1093
|
return {
|
|
@@ -1099,6 +1109,7 @@ function SlotsProvider({ children }) {
|
|
|
1099
1109
|
});
|
|
1100
1110
|
}, []);
|
|
1101
1111
|
const clearSlotForSource = useCallback((slot, sourceTrait) => {
|
|
1112
|
+
xOrbitalLog.info("slot-clear-source", { slot, sourceTrait });
|
|
1102
1113
|
setSlots((prev) => {
|
|
1103
1114
|
const existing = prev[slot];
|
|
1104
1115
|
if (!existing || !(sourceTrait in existing)) return prev;
|
|
@@ -1139,11 +1150,12 @@ function useSlotsActions() {
|
|
|
1139
1150
|
}
|
|
1140
1151
|
return actions;
|
|
1141
1152
|
}
|
|
1142
|
-
var slotLog, refIds, nextRefId, DEFAULT_SOURCE_KEY, SlotsStateContext, SlotsActionsContext;
|
|
1153
|
+
var slotLog, xOrbitalLog, refIds, nextRefId, DEFAULT_SOURCE_KEY, SlotsStateContext, SlotsActionsContext;
|
|
1143
1154
|
var init_SlotsContext = __esm({
|
|
1144
1155
|
"runtime/ui/SlotsContext.tsx"() {
|
|
1145
1156
|
init_logger();
|
|
1146
1157
|
slotLog = createLogger("almadar:ui:slot-render");
|
|
1158
|
+
xOrbitalLog = createLogger("almadar:runtime:cross-orbital");
|
|
1147
1159
|
refIds = /* @__PURE__ */ new WeakMap();
|
|
1148
1160
|
nextRefId = 1;
|
|
1149
1161
|
DEFAULT_SOURCE_KEY = "__default__";
|
|
@@ -8137,7 +8149,7 @@ var init_MapView = __esm({
|
|
|
8137
8149
|
shadowSize: [41, 41]
|
|
8138
8150
|
});
|
|
8139
8151
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
8140
|
-
const { useEffect: useEffect68, useRef: useRef65, useCallback: useCallback110, useState:
|
|
8152
|
+
const { useEffect: useEffect68, useRef: useRef65, useCallback: useCallback110, useState: useState102 } = React115__default;
|
|
8141
8153
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
8142
8154
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
8143
8155
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -8181,7 +8193,7 @@ var init_MapView = __esm({
|
|
|
8181
8193
|
showAttribution = true
|
|
8182
8194
|
}) {
|
|
8183
8195
|
const eventBus = useEventBus2();
|
|
8184
|
-
const [clickedPosition, setClickedPosition] =
|
|
8196
|
+
const [clickedPosition, setClickedPosition] = useState102(null);
|
|
8185
8197
|
const handleMapClick = useCallback110((lat, lng) => {
|
|
8186
8198
|
if (showClickedPin) {
|
|
8187
8199
|
setClickedPosition({ lat, lng });
|
|
@@ -38134,6 +38146,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
38134
38146
|
const eventBus = useEventBus();
|
|
38135
38147
|
const { entities } = useEntitySchema();
|
|
38136
38148
|
const traitConfigsByName = options?.traitConfigsByName;
|
|
38149
|
+
const orbitalsByTrait = options?.orbitalsByTrait;
|
|
38137
38150
|
const manager = useMemo(() => {
|
|
38138
38151
|
const traitDefs = traitBindings.map(toTraitDefinition);
|
|
38139
38152
|
const m = new StateMachineManager(traitDefs);
|
|
@@ -38346,24 +38359,7 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
38346
38359
|
const actions = slotsActionsRef.current;
|
|
38347
38360
|
console.log("[TraitStateMachine] Processing event:", normalizedEvent, "payload:", payload);
|
|
38348
38361
|
const bindingMap = new Map(bindings.map((b) => [b.trait.name, b]));
|
|
38349
|
-
for (const traitName of bindingMap.keys()) {
|
|
38350
|
-
const traitState = currentManager.getState(traitName);
|
|
38351
|
-
eventBus.emit(`${traitName}:DISPATCH`, {
|
|
38352
|
-
event: normalizedEvent,
|
|
38353
|
-
payload,
|
|
38354
|
-
currentState: traitState?.currentState
|
|
38355
|
-
});
|
|
38356
|
-
}
|
|
38357
38362
|
const results = currentManager.sendEvent(normalizedEvent, payload);
|
|
38358
|
-
for (const { traitName, result } of results) {
|
|
38359
|
-
const suffix = result.executed ? "SUCCESS" : "ERROR";
|
|
38360
|
-
eventBus.emit(`${traitName}:${normalizedEvent}:${suffix}`, {
|
|
38361
|
-
event: normalizedEvent,
|
|
38362
|
-
payload,
|
|
38363
|
-
newState: result.newState,
|
|
38364
|
-
currentState: result.previousState
|
|
38365
|
-
});
|
|
38366
|
-
}
|
|
38367
38363
|
const emittedByTrait = /* @__PURE__ */ new Map();
|
|
38368
38364
|
for (const { traitName, result } of results) {
|
|
38369
38365
|
const binding = bindingMap.get(traitName);
|
|
@@ -38599,7 +38595,10 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
38599
38595
|
if (!LIFECYCLE_EVENTS.has(normalizedEvent)) {
|
|
38600
38596
|
for (const { traitName, result } of results) {
|
|
38601
38597
|
if (!result.executed) continue;
|
|
38602
|
-
|
|
38598
|
+
const orbitalName = orbitalsByTrait?.[traitName];
|
|
38599
|
+
if (!orbitalName) continue;
|
|
38600
|
+
eventBus.emit(`UI:${orbitalName}.${traitName}.${normalizedEvent}`, payload, {
|
|
38601
|
+
orbital: orbitalName,
|
|
38603
38602
|
trait: traitName,
|
|
38604
38603
|
fromBridge: true
|
|
38605
38604
|
});
|
|
@@ -38610,7 +38609,13 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
38610
38609
|
}
|
|
38611
38610
|
const onEventProcessed = optionsRef.current?.onEventProcessed;
|
|
38612
38611
|
if (onEventProcessed) {
|
|
38613
|
-
|
|
38612
|
+
const dispatchedOrbitals = /* @__PURE__ */ new Set();
|
|
38613
|
+
for (const { traitName, result } of results) {
|
|
38614
|
+
if (!result.executed) continue;
|
|
38615
|
+
const orbital = orbitalsByTrait?.[traitName];
|
|
38616
|
+
if (orbital) dispatchedOrbitals.add(orbital);
|
|
38617
|
+
}
|
|
38618
|
+
await onEventProcessed(normalizedEvent, payload, dispatchedOrbitals);
|
|
38614
38619
|
}
|
|
38615
38620
|
}, [entities, eventBus]);
|
|
38616
38621
|
const drainEventQueue = useCallback(async () => {
|
|
@@ -38654,26 +38659,34 @@ function useTraitStateMachine(traitBindings, slotsActions, options) {
|
|
|
38654
38659
|
}
|
|
38655
38660
|
console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
|
|
38656
38661
|
const unsubscribes = [];
|
|
38657
|
-
for (const
|
|
38658
|
-
|
|
38659
|
-
|
|
38662
|
+
for (const binding of traitBindings) {
|
|
38663
|
+
const traitName = binding.trait.name;
|
|
38664
|
+
const orbitalName = orbitalsByTrait?.[traitName];
|
|
38665
|
+
if (!orbitalName) continue;
|
|
38666
|
+
for (const transition of binding.trait.transitions) {
|
|
38667
|
+
const eventKey = transition.event;
|
|
38668
|
+
if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
|
|
38669
|
+
continue;
|
|
38670
|
+
}
|
|
38671
|
+
const unsub = eventBus.on(`UI:${orbitalName}.${traitName}.${eventKey}`, (event) => {
|
|
38672
|
+
if (event.source && event.source.fromBridge) {
|
|
38673
|
+
return;
|
|
38674
|
+
}
|
|
38675
|
+
enqueueAndDrain(eventKey, event.payload);
|
|
38676
|
+
});
|
|
38677
|
+
unsubscribes.push(unsub);
|
|
38660
38678
|
}
|
|
38661
|
-
const unsub = eventBus.on(`UI:${eventKey}`, (event) => {
|
|
38662
|
-
console.log("[TraitStateMachine] Received event:", `UI:${eventKey}`, event);
|
|
38663
|
-
enqueueAndDrain(eventKey, event.payload);
|
|
38664
|
-
});
|
|
38665
|
-
unsubscribes.push(unsub);
|
|
38666
38679
|
}
|
|
38667
38680
|
for (const binding of traitBindings) {
|
|
38681
|
+
const ownOrbital = orbitalsByTrait?.[binding.trait.name];
|
|
38668
38682
|
const listens = binding.trait.listens ?? [];
|
|
38669
38683
|
for (const listen of listens) {
|
|
38670
|
-
const
|
|
38671
|
-
|
|
38672
|
-
|
|
38673
|
-
|
|
38674
|
-
|
|
38675
|
-
|
|
38676
|
-
console.log("[TraitStateMachine] listens", binding.trait.name, listen.event, "\u2192", listen.triggers, "from", event.source?.trait);
|
|
38684
|
+
const sourceTrait = listen.source?.trait;
|
|
38685
|
+
if (!sourceTrait) continue;
|
|
38686
|
+
const sourceOrbital = listen.source?.orbital ?? ownOrbital;
|
|
38687
|
+
if (!sourceOrbital) continue;
|
|
38688
|
+
const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
|
|
38689
|
+
const unsub = eventBus.on(busKey, (event) => {
|
|
38677
38690
|
enqueueAndDrain(listen.triggers, event.payload);
|
|
38678
38691
|
});
|
|
38679
38692
|
unsubscribes.push(unsub);
|
|
@@ -38820,6 +38833,8 @@ init_EntitySchemaContext();
|
|
|
38820
38833
|
|
|
38821
38834
|
// runtime/ServerBridge.tsx
|
|
38822
38835
|
init_useEventBus();
|
|
38836
|
+
init_logger();
|
|
38837
|
+
var xOrbitalLog2 = createLogger("almadar:runtime:cross-orbital");
|
|
38823
38838
|
var ServerBridgeContext = createContext(null);
|
|
38824
38839
|
function useServerBridge() {
|
|
38825
38840
|
const ctx = useContext(ServerBridgeContext);
|
|
@@ -38897,8 +38912,22 @@ function ServerBridgeProvider({
|
|
|
38897
38912
|
}
|
|
38898
38913
|
if (result.emittedEvents) {
|
|
38899
38914
|
for (const emitted of result.emittedEvents) {
|
|
38900
|
-
|
|
38901
|
-
|
|
38915
|
+
const evTrait = emitted.source?.trait;
|
|
38916
|
+
if (!evTrait) {
|
|
38917
|
+
xOrbitalLog2.warn("emit:dropped-no-source", {
|
|
38918
|
+
event: emitted.event,
|
|
38919
|
+
dispatchOrbital: orbitalName
|
|
38920
|
+
});
|
|
38921
|
+
continue;
|
|
38922
|
+
}
|
|
38923
|
+
const key = emitted.source?.orbital ? `UI:${emitted.source.orbital}.${evTrait}.${emitted.event}` : `UI:${evTrait}.${emitted.event}`;
|
|
38924
|
+
xOrbitalLog2.info("emit:rebroadcast", {
|
|
38925
|
+
busKey: key,
|
|
38926
|
+
sourceOrbital: emitted.source?.orbital,
|
|
38927
|
+
sourceTrait: evTrait,
|
|
38928
|
+
dispatchOrbital: orbitalName
|
|
38929
|
+
});
|
|
38930
|
+
eventBus.emit(key, emitted.payload);
|
|
38902
38931
|
}
|
|
38903
38932
|
}
|
|
38904
38933
|
} else if (result.error) {
|
|
@@ -39019,6 +39048,10 @@ function prepareSchemaForPreview(input) {
|
|
|
39019
39048
|
const schema = adjustSchemaForMockData(parsed, mockData);
|
|
39020
39049
|
return { schema, mockData };
|
|
39021
39050
|
}
|
|
39051
|
+
|
|
39052
|
+
// runtime/OrbPreview.tsx
|
|
39053
|
+
init_logger();
|
|
39054
|
+
var xOrbitalLog3 = createLogger("almadar:runtime:cross-orbital");
|
|
39022
39055
|
function normalizeChild(child) {
|
|
39023
39056
|
if (typeof child === "string") return child;
|
|
39024
39057
|
if (child === null || typeof child !== "object" || Array.isArray(child)) {
|
|
@@ -39098,6 +39131,11 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
|
39098
39131
|
const patternRecord = eff.pattern;
|
|
39099
39132
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
39100
39133
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
39134
|
+
xOrbitalLog3.info("slot-write", {
|
|
39135
|
+
slot: eff.slot,
|
|
39136
|
+
sourceTrait: eff.traitName ?? "server",
|
|
39137
|
+
patternType: typeof patternType === "string" ? patternType : void 0
|
|
39138
|
+
});
|
|
39101
39139
|
uiSlots.render({
|
|
39102
39140
|
target: eff.slot,
|
|
39103
39141
|
pattern: patternType,
|
|
@@ -39112,19 +39150,26 @@ function applyServerEffects(effects, uiSlots, onNavigate) {
|
|
|
39112
39150
|
}
|
|
39113
39151
|
}
|
|
39114
39152
|
}
|
|
39115
|
-
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName }) {
|
|
39153
|
+
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFallback, persistence, traitConfigsByName, orbitalsByTrait }) {
|
|
39116
39154
|
const slotsActions = useSlotsActions();
|
|
39117
39155
|
const bridge = useServerBridge();
|
|
39118
39156
|
const uiSlots = useUISlots();
|
|
39119
|
-
const onEventProcessed = useCallback(async (event, payload) => {
|
|
39157
|
+
const onEventProcessed = useCallback(async (event, payload, dispatchedOrbitals) => {
|
|
39120
39158
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
39121
|
-
|
|
39159
|
+
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
39160
|
+
xOrbitalLog3.info("TraitInitializer:fanout", {
|
|
39161
|
+
event,
|
|
39162
|
+
sentTo: targets,
|
|
39163
|
+
skipped: orbitalNames.filter((n) => !targets.includes(n)),
|
|
39164
|
+
dispatchedOrbitalsSize: dispatchedOrbitals?.size ?? 0
|
|
39165
|
+
});
|
|
39166
|
+
for (const name of targets) {
|
|
39122
39167
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
39123
39168
|
recordServerResponse(name, event, meta);
|
|
39124
39169
|
applyServerEffects(effects, uiSlots, onNavigate);
|
|
39125
39170
|
}
|
|
39126
39171
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate]);
|
|
39127
|
-
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName } : { navigate: onNavigate, persistence, traitConfigsByName };
|
|
39172
|
+
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, traitConfigsByName, orbitalsByTrait } : { navigate: onNavigate, persistence, traitConfigsByName, orbitalsByTrait };
|
|
39128
39173
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
39129
39174
|
const initSentRef = useRef(false);
|
|
39130
39175
|
useEffect(() => {
|
|
@@ -39174,27 +39219,68 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
|
|
|
39174
39219
|
const allPageTraits = useMemo(() => {
|
|
39175
39220
|
if (pageName && traits2.length > 0) return traits2;
|
|
39176
39221
|
if (!ir?.pages || ir.pages.size <= 1) return traits2;
|
|
39177
|
-
const
|
|
39222
|
+
const firstPage = ir.pages.values().next().value;
|
|
39223
|
+
if (!firstPage) return traits2;
|
|
39224
|
+
const firstPageTraits = [];
|
|
39178
39225
|
const seen = /* @__PURE__ */ new Set();
|
|
39179
|
-
for (const
|
|
39180
|
-
|
|
39181
|
-
|
|
39182
|
-
|
|
39183
|
-
|
|
39184
|
-
if (name && !seen.has(name)) {
|
|
39185
|
-
seen.add(name);
|
|
39186
|
-
combined.push(t);
|
|
39187
|
-
}
|
|
39226
|
+
for (const binding of firstPage.traits) {
|
|
39227
|
+
const name = binding.trait.name;
|
|
39228
|
+
if (name && !seen.has(name)) {
|
|
39229
|
+
seen.add(name);
|
|
39230
|
+
firstPageTraits.push(binding);
|
|
39188
39231
|
}
|
|
39189
39232
|
}
|
|
39190
|
-
return
|
|
39233
|
+
return firstPageTraits.length > 0 ? firstPageTraits : traits2;
|
|
39191
39234
|
}, [ir, traits2, pageName]);
|
|
39192
|
-
|
|
39235
|
+
useMemo(() => {
|
|
39193
39236
|
const parsed = schema;
|
|
39194
39237
|
const orbitals = parsed?.orbitals;
|
|
39195
39238
|
if (!orbitals) return [];
|
|
39196
39239
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
39197
39240
|
}, [schema]);
|
|
39241
|
+
const orbitalsByTrait = useMemo(() => {
|
|
39242
|
+
const map = {};
|
|
39243
|
+
const parsed = schema;
|
|
39244
|
+
if (!parsed?.orbitals) return map;
|
|
39245
|
+
for (const orb of parsed.orbitals) {
|
|
39246
|
+
for (const traitRef of orb.traits) {
|
|
39247
|
+
let traitName;
|
|
39248
|
+
if (typeof traitRef === "string") {
|
|
39249
|
+
const parts = traitRef.split(".");
|
|
39250
|
+
traitName = parts[parts.length - 1];
|
|
39251
|
+
} else if ("ref" in traitRef && typeof traitRef.ref === "string") {
|
|
39252
|
+
const parts = traitRef.ref.split(".");
|
|
39253
|
+
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
39254
|
+
} else if ("name" in traitRef && typeof traitRef.name === "string") {
|
|
39255
|
+
traitName = traitRef.name;
|
|
39256
|
+
}
|
|
39257
|
+
if (traitName) map[traitName] = orb.name;
|
|
39258
|
+
}
|
|
39259
|
+
}
|
|
39260
|
+
return map;
|
|
39261
|
+
}, [schema]);
|
|
39262
|
+
const pageOrbitalNames = useMemo(() => {
|
|
39263
|
+
const set = /* @__PURE__ */ new Set();
|
|
39264
|
+
for (const binding of allPageTraits) {
|
|
39265
|
+
const orb = orbitalsByTrait[binding.trait.name];
|
|
39266
|
+
if (orb) set.add(orb);
|
|
39267
|
+
}
|
|
39268
|
+
return Array.from(set);
|
|
39269
|
+
}, [allPageTraits, orbitalsByTrait]);
|
|
39270
|
+
useEffect(() => {
|
|
39271
|
+
const traitNames = allPageTraits.map((b) => b.trait.name);
|
|
39272
|
+
const orbitalsByTraitForPage = {};
|
|
39273
|
+
for (const name of traitNames) {
|
|
39274
|
+
const orb = orbitalsByTrait[name];
|
|
39275
|
+
if (orb) orbitalsByTraitForPage[name] = orb;
|
|
39276
|
+
}
|
|
39277
|
+
xOrbitalLog3.info("SchemaRunner:mount", {
|
|
39278
|
+
pageName,
|
|
39279
|
+
traitNames,
|
|
39280
|
+
orbitalsByTraitForPage,
|
|
39281
|
+
pageOrbitalNames: pageOrbitalNames.join(",")
|
|
39282
|
+
});
|
|
39283
|
+
}, [pageName, allPageTraits, orbitalsByTrait, pageOrbitalNames]);
|
|
39198
39284
|
const traitConfigsByName = useMemo(() => {
|
|
39199
39285
|
const map = {};
|
|
39200
39286
|
const parsed = schema;
|
|
@@ -39235,8 +39321,9 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate, onLoc
|
|
|
39235
39321
|
TraitInitializer,
|
|
39236
39322
|
{
|
|
39237
39323
|
traits: allPageTraits,
|
|
39238
|
-
orbitalNames: serverUrl ?
|
|
39324
|
+
orbitalNames: serverUrl ? pageOrbitalNames : void 0,
|
|
39239
39325
|
traitConfigsByName,
|
|
39326
|
+
orbitalsByTrait,
|
|
39240
39327
|
onNavigate,
|
|
39241
39328
|
onLocalFallback,
|
|
39242
39329
|
persistence
|
|
@@ -39258,7 +39345,8 @@ function OrbPreview({
|
|
|
39258
39345
|
autoMock = false,
|
|
39259
39346
|
height = "400px",
|
|
39260
39347
|
className,
|
|
39261
|
-
serverUrl
|
|
39348
|
+
serverUrl,
|
|
39349
|
+
initialPagePath
|
|
39262
39350
|
}) {
|
|
39263
39351
|
const [localFallback, setLocalFallback] = useState(false);
|
|
39264
39352
|
const eventBus = useEventBus();
|
|
@@ -39304,7 +39392,17 @@ function OrbPreview({
|
|
|
39304
39392
|
return [];
|
|
39305
39393
|
}
|
|
39306
39394
|
}, [parsedSchema]);
|
|
39307
|
-
const
|
|
39395
|
+
const initialPageName = useMemo(() => {
|
|
39396
|
+
if (!initialPagePath) return void 0;
|
|
39397
|
+
const match = pages.find(({ page }) => page.path === initialPagePath);
|
|
39398
|
+
return match?.page.name;
|
|
39399
|
+
}, [pages, initialPagePath]);
|
|
39400
|
+
const [currentPage, setCurrentPage] = useState(initialPageName);
|
|
39401
|
+
useEffect(() => {
|
|
39402
|
+
if (initialPageName && initialPageName !== currentPage) {
|
|
39403
|
+
setCurrentPage(initialPageName);
|
|
39404
|
+
}
|
|
39405
|
+
}, [initialPageName, currentPage]);
|
|
39308
39406
|
const handleNavigate = useCallback((path) => {
|
|
39309
39407
|
const match = pages.find(({ page }) => page.path === path);
|
|
39310
39408
|
if (match) {
|
|
@@ -32,8 +32,18 @@ export interface TraitStateMachineResult {
|
|
|
32
32
|
canHandleEvent: (traitName: string, eventKey: string) => boolean;
|
|
33
33
|
}
|
|
34
34
|
export interface UseTraitStateMachineOptions {
|
|
35
|
-
/**
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Callback invoked after each event is processed (for server forwarding).
|
|
37
|
+
*
|
|
38
|
+
* `dispatchedOrbitals` is the set of orbital names whose traits actually
|
|
39
|
+
* executed a transition for this event. The server-bridge fan-out should
|
|
40
|
+
* be scoped to this set; sending the event to other orbitals fires
|
|
41
|
+
* same-named transitions in unrelated orbitals and stacks their UI into
|
|
42
|
+
* the wrong slot (gap #11 in `docs/Almadar_Std_Verification.md`). Empty
|
|
43
|
+
* set means no local transition matched — leave the legacy fallback to
|
|
44
|
+
* the consumer.
|
|
45
|
+
*/
|
|
46
|
+
onEventProcessed?: (eventKey: string, payload?: EventPayload, dispatchedOrbitals?: Set<string>) => void | Promise<void>;
|
|
37
47
|
/** Router navigate function for navigate effects */
|
|
38
48
|
navigate?: (path: string, params?: Record<string, unknown>) => void;
|
|
39
49
|
/** Notification function for notify effects */
|
|
@@ -57,6 +67,15 @@ export interface UseTraitStateMachineOptions {
|
|
|
57
67
|
* caller assembles this map from the orbital schema directly.
|
|
58
68
|
*/
|
|
59
69
|
traitConfigsByName?: Record<string, import('@almadar/core').TraitConfig>;
|
|
70
|
+
/**
|
|
71
|
+
* Trait → orbital map built from `schema.orbitals[].traits[]` by the
|
|
72
|
+
* caller. Threaded down so bus emits (`UI:Orbital.Trait.Event`) and
|
|
73
|
+
* subscriptions can carry the qualified `Orbital.Trait` scope —
|
|
74
|
+
* gap #13 unification. Same mechanism as `traitConfigsByName`: the
|
|
75
|
+
* orbital boundary doesn't propagate through `@almadar/core`'s
|
|
76
|
+
* `ResolvedTraitBinding`, so the caller assembles the map directly.
|
|
77
|
+
*/
|
|
78
|
+
orbitalsByTrait?: Record<string, string>;
|
|
60
79
|
}
|
|
61
80
|
/**
|
|
62
81
|
* useTraitStateMachine - Manages state machines for multiple traits
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.7.0",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/components/index.js",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"@almadar/core": "^7.0.0",
|
|
122
122
|
"@almadar/evaluator": ">=2.9.2",
|
|
123
123
|
"@almadar/patterns": ">=2.17.1",
|
|
124
|
-
"@almadar/runtime": "^5.
|
|
124
|
+
"@almadar/runtime": "^5.5.0",
|
|
125
125
|
"@almadar/std": ">=6.4.1",
|
|
126
126
|
"@almadar/syntax": ">=1.3.1",
|
|
127
127
|
"@xyflow/react": "12.10.1",
|