@almadar/ui 4.15.3 → 4.15.5
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 +71 -23
- package/dist/avl/index.js +72 -24
- package/dist/components/index.cjs +16 -1
- package/dist/components/index.js +16 -1
- package/dist/context/index.cjs +62 -1
- package/dist/context/index.js +62 -1
- package/dist/hooks/index.cjs +13 -1
- package/dist/hooks/index.js +13 -1
- package/dist/runtime/index.cjs +60 -21
- package/dist/runtime/index.js +61 -22
- package/package.json +3 -3
package/dist/avl/index.cjs
CHANGED
|
@@ -4348,6 +4348,13 @@ function useUISlotManager() {
|
|
|
4348
4348
|
indexTraitRender(content.sourceTrait, content);
|
|
4349
4349
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
4350
4350
|
}
|
|
4351
|
+
slotLog.info("slot:written", {
|
|
4352
|
+
slot: config.target,
|
|
4353
|
+
sourceKey,
|
|
4354
|
+
sourceTrait: content.sourceTrait,
|
|
4355
|
+
patternType: content.pattern,
|
|
4356
|
+
priority: content.priority
|
|
4357
|
+
});
|
|
4351
4358
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
4352
4359
|
return nextAll;
|
|
4353
4360
|
});
|
|
@@ -4385,7 +4392,10 @@ function useUISlotManager() {
|
|
|
4385
4392
|
const sourceKey = sourceTrait;
|
|
4386
4393
|
setSources((prev) => {
|
|
4387
4394
|
const slotSources = prev[slot];
|
|
4388
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
4395
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
4396
|
+
slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
4397
|
+
return prev;
|
|
4398
|
+
}
|
|
4389
4399
|
const content = slotSources[sourceKey];
|
|
4390
4400
|
const timer = timersRef.current.get(content.id);
|
|
4391
4401
|
if (timer) {
|
|
@@ -4399,6 +4409,7 @@ function useUISlotManager() {
|
|
|
4399
4409
|
}
|
|
4400
4410
|
const nextSources = { ...slotSources };
|
|
4401
4411
|
delete nextSources[sourceKey];
|
|
4412
|
+
slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
4402
4413
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
4403
4414
|
return { ...prev, [slot]: nextSources };
|
|
4404
4415
|
});
|
|
@@ -4517,10 +4528,12 @@ function useUISlotManager() {
|
|
|
4517
4528
|
updateTraitContent
|
|
4518
4529
|
};
|
|
4519
4530
|
}
|
|
4520
|
-
var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
4531
|
+
var slotLog, DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
4521
4532
|
var init_useUISlots = __esm({
|
|
4522
4533
|
"hooks/useUISlots.ts"() {
|
|
4523
4534
|
"use client";
|
|
4535
|
+
init_logger();
|
|
4536
|
+
slotLog = createLogger("almadar:ui:useUISlots");
|
|
4524
4537
|
DEFAULT_SOURCE_KEY = "__default__";
|
|
4525
4538
|
MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
4526
4539
|
ALL_SLOTS = [
|
|
@@ -5426,11 +5439,11 @@ function refId(obj) {
|
|
|
5426
5439
|
refIds.set(obj, id);
|
|
5427
5440
|
return id;
|
|
5428
5441
|
}
|
|
5429
|
-
var
|
|
5442
|
+
var slotLog2, refIds, nextRefId;
|
|
5430
5443
|
var init_slot_types = __esm({
|
|
5431
5444
|
"runtime/ui/slot-types.ts"() {
|
|
5432
5445
|
init_logger();
|
|
5433
|
-
|
|
5446
|
+
slotLog2 = createLogger("almadar:ui:slot-render");
|
|
5434
5447
|
refIds = /* @__PURE__ */ new WeakMap();
|
|
5435
5448
|
nextRefId = 1;
|
|
5436
5449
|
}
|
|
@@ -47008,7 +47021,7 @@ function SlotContentRenderer({
|
|
|
47008
47021
|
}) {
|
|
47009
47022
|
const entityProp = content.props.entity;
|
|
47010
47023
|
if (content.pattern === "form-section") {
|
|
47011
|
-
|
|
47024
|
+
slotLog2.debug("SlotContentRenderer:form-section-render", {
|
|
47012
47025
|
contentId: content.id,
|
|
47013
47026
|
sourceTrait: content.sourceTrait,
|
|
47014
47027
|
entityRefId: refId(entityProp),
|
|
@@ -51757,6 +51770,7 @@ init_traitRegistry();
|
|
|
51757
51770
|
init_verificationRegistry();
|
|
51758
51771
|
var crossTraitLog = createLogger("almadar:ui:cross-trait");
|
|
51759
51772
|
var flushLog = createLogger("almadar:ui:slot-flush");
|
|
51773
|
+
var stateLog = createLogger("almadar:ui:state-transitions");
|
|
51760
51774
|
function toTraitDefinition(binding) {
|
|
51761
51775
|
return {
|
|
51762
51776
|
name: binding.trait.name,
|
|
@@ -52117,8 +52131,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52117
52131
|
payload: payload || {},
|
|
52118
52132
|
state: result.previousState
|
|
52119
52133
|
};
|
|
52120
|
-
|
|
52121
|
-
|
|
52134
|
+
const sharedDeclared = runtime.collectDeclaredConfigDefaults(
|
|
52135
|
+
binding.trait
|
|
52136
|
+
);
|
|
52137
|
+
const sharedCallSite = binding.config;
|
|
52138
|
+
if (sharedDeclared || sharedCallSite) {
|
|
52139
|
+
sharedBindings.config = {
|
|
52140
|
+
...sharedDeclared ?? {},
|
|
52141
|
+
...sharedCallSite ?? {}
|
|
52142
|
+
};
|
|
52122
52143
|
}
|
|
52123
52144
|
const serverHandlers = runtime.createServerEffectHandlers({
|
|
52124
52145
|
persistence,
|
|
@@ -52152,8 +52173,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52152
52173
|
payload: payload || {},
|
|
52153
52174
|
state: result.previousState
|
|
52154
52175
|
};
|
|
52155
|
-
|
|
52156
|
-
|
|
52176
|
+
const declaredDefaults = runtime.collectDeclaredConfigDefaults(
|
|
52177
|
+
binding.trait
|
|
52178
|
+
);
|
|
52179
|
+
const callSiteConfig = binding.config;
|
|
52180
|
+
if (declaredDefaults || callSiteConfig) {
|
|
52181
|
+
bindingCtx.config = {
|
|
52182
|
+
...declaredDefaults ?? {},
|
|
52183
|
+
...callSiteConfig ?? {}
|
|
52184
|
+
};
|
|
52157
52185
|
}
|
|
52158
52186
|
const effectContext = {
|
|
52159
52187
|
traitName: binding.trait.name,
|
|
@@ -52175,21 +52203,29 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52175
52203
|
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
52176
52204
|
try {
|
|
52177
52205
|
await executor.executeAll(result.effects);
|
|
52178
|
-
|
|
52179
|
-
|
|
52180
|
-
|
|
52181
|
-
|
|
52206
|
+
stateLog.info("transition:render-ui-dispatched", {
|
|
52207
|
+
traitName,
|
|
52208
|
+
fromState: result.previousState,
|
|
52209
|
+
toState: result.newState,
|
|
52210
|
+
event: eventKey,
|
|
52211
|
+
slotsTouched: Array.from(pendingSlots.keys()).join(","),
|
|
52212
|
+
patternTypes: Array.from(pendingSlots.entries()).map(
|
|
52213
|
+
([slot, patterns]) => `${slot}:[${patterns.map((p2) => p2.pattern?.type ?? "null").join(",")}]`
|
|
52214
|
+
).join(";")
|
|
52215
|
+
});
|
|
52182
52216
|
void slotSource;
|
|
52183
52217
|
for (const [slot, patterns] of pendingSlots) {
|
|
52184
52218
|
flushSlot(traitName, slot, patterns);
|
|
52185
52219
|
}
|
|
52186
52220
|
} catch (error) {
|
|
52187
|
-
|
|
52188
|
-
|
|
52189
|
-
|
|
52190
|
-
|
|
52191
|
-
|
|
52192
|
-
|
|
52221
|
+
stateLog.error("transition:effect-error", {
|
|
52222
|
+
traitName,
|
|
52223
|
+
fromState: result.previousState,
|
|
52224
|
+
toState: result.newState,
|
|
52225
|
+
event: eventKey,
|
|
52226
|
+
error: error instanceof Error ? error.message : String(error),
|
|
52227
|
+
effectCount: result.effects.length
|
|
52228
|
+
});
|
|
52193
52229
|
}
|
|
52194
52230
|
} else if (!result.executed) {
|
|
52195
52231
|
if (result.guardResult === false) {
|
|
@@ -52335,13 +52371,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52335
52371
|
if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
|
|
52336
52372
|
continue;
|
|
52337
52373
|
}
|
|
52338
|
-
const
|
|
52374
|
+
const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
|
|
52375
|
+
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
52376
|
+
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
52339
52377
|
if (event.source && event.source.fromBridge) {
|
|
52378
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
52340
52379
|
return;
|
|
52341
52380
|
}
|
|
52381
|
+
crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
52342
52382
|
enqueueAndDrain(eventKey, event.payload);
|
|
52343
52383
|
});
|
|
52344
|
-
unsubscribes.push(
|
|
52384
|
+
unsubscribes.push(() => {
|
|
52385
|
+
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
52386
|
+
unsub();
|
|
52387
|
+
});
|
|
52345
52388
|
}
|
|
52346
52389
|
}
|
|
52347
52390
|
for (const binding of traitBindings) {
|
|
@@ -52359,18 +52402,23 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52359
52402
|
const sourceOrbital = listen.source?.orbital ?? ownOrbital;
|
|
52360
52403
|
if (!sourceOrbital) continue;
|
|
52361
52404
|
const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
|
|
52362
|
-
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
52405
|
+
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, sourceOrbital, sourceTrait, listenEvent: listen.event, triggers: listen.triggers });
|
|
52363
52406
|
const unsub = eventBus.on(busKey, (event) => {
|
|
52364
52407
|
crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
52365
52408
|
enqueueAndDrain(listen.triggers, event.payload);
|
|
52366
52409
|
});
|
|
52367
|
-
unsubscribes.push(
|
|
52410
|
+
unsubscribes.push(() => {
|
|
52411
|
+
crossTraitLog.debug("listen:unsubscribe", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
52412
|
+
unsub();
|
|
52413
|
+
});
|
|
52368
52414
|
}
|
|
52369
52415
|
}
|
|
52370
52416
|
return () => {
|
|
52417
|
+
crossTraitLog.debug("cleanup:start", { unsubscribeCount: unsubscribes.length });
|
|
52371
52418
|
for (const unsub of unsubscribes) {
|
|
52372
52419
|
unsub();
|
|
52373
52420
|
}
|
|
52421
|
+
crossTraitLog.debug("cleanup:done", {});
|
|
52374
52422
|
};
|
|
52375
52423
|
}, [traitBindings, eventBus, enqueueAndDrain]);
|
|
52376
52424
|
return {
|
package/dist/avl/index.js
CHANGED
|
@@ -43,7 +43,7 @@ import { EffectComposer, Bloom, DepthOfField, Vignette } from '@react-three/post
|
|
|
43
43
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
|
44
44
|
import { MarkerType, Handle, Position, getBezierPath, EdgeLabelRenderer, BaseEdge, ReactFlowProvider, useNodesState, useEdgesState, useReactFlow, ReactFlow, Controls, Background, BackgroundVariant } from '@xyflow/react';
|
|
45
45
|
import '@tanstack/react-query';
|
|
46
|
-
import { InMemoryPersistence, StateMachineManager, createContextFromBindings, interpolateValue, createServerEffectHandlers, EffectExecutor } from '@almadar/runtime';
|
|
46
|
+
import { InMemoryPersistence, StateMachineManager, createContextFromBindings, interpolateValue, collectDeclaredConfigDefaults, createServerEffectHandlers, EffectExecutor } from '@almadar/runtime';
|
|
47
47
|
|
|
48
48
|
var __defProp = Object.defineProperty;
|
|
49
49
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -4302,6 +4302,13 @@ function useUISlotManager() {
|
|
|
4302
4302
|
indexTraitRender(content.sourceTrait, content);
|
|
4303
4303
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
4304
4304
|
}
|
|
4305
|
+
slotLog.info("slot:written", {
|
|
4306
|
+
slot: config.target,
|
|
4307
|
+
sourceKey,
|
|
4308
|
+
sourceTrait: content.sourceTrait,
|
|
4309
|
+
patternType: content.pattern,
|
|
4310
|
+
priority: content.priority
|
|
4311
|
+
});
|
|
4305
4312
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
4306
4313
|
return nextAll;
|
|
4307
4314
|
});
|
|
@@ -4339,7 +4346,10 @@ function useUISlotManager() {
|
|
|
4339
4346
|
const sourceKey = sourceTrait;
|
|
4340
4347
|
setSources((prev) => {
|
|
4341
4348
|
const slotSources = prev[slot];
|
|
4342
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
4349
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
4350
|
+
slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
4351
|
+
return prev;
|
|
4352
|
+
}
|
|
4343
4353
|
const content = slotSources[sourceKey];
|
|
4344
4354
|
const timer = timersRef.current.get(content.id);
|
|
4345
4355
|
if (timer) {
|
|
@@ -4353,6 +4363,7 @@ function useUISlotManager() {
|
|
|
4353
4363
|
}
|
|
4354
4364
|
const nextSources = { ...slotSources };
|
|
4355
4365
|
delete nextSources[sourceKey];
|
|
4366
|
+
slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
4356
4367
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
4357
4368
|
return { ...prev, [slot]: nextSources };
|
|
4358
4369
|
});
|
|
@@ -4471,10 +4482,12 @@ function useUISlotManager() {
|
|
|
4471
4482
|
updateTraitContent
|
|
4472
4483
|
};
|
|
4473
4484
|
}
|
|
4474
|
-
var DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
4485
|
+
var slotLog, DEFAULT_SOURCE_KEY, MULTI_SOURCE_STACK_TRAIT, ALL_SLOTS, DEFAULT_SLOTS, DEFAULT_SOURCES, idCounter;
|
|
4475
4486
|
var init_useUISlots = __esm({
|
|
4476
4487
|
"hooks/useUISlots.ts"() {
|
|
4477
4488
|
"use client";
|
|
4489
|
+
init_logger();
|
|
4490
|
+
slotLog = createLogger("almadar:ui:useUISlots");
|
|
4478
4491
|
DEFAULT_SOURCE_KEY = "__default__";
|
|
4479
4492
|
MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
4480
4493
|
ALL_SLOTS = [
|
|
@@ -5380,11 +5393,11 @@ function refId(obj) {
|
|
|
5380
5393
|
refIds.set(obj, id);
|
|
5381
5394
|
return id;
|
|
5382
5395
|
}
|
|
5383
|
-
var
|
|
5396
|
+
var slotLog2, refIds, nextRefId;
|
|
5384
5397
|
var init_slot_types = __esm({
|
|
5385
5398
|
"runtime/ui/slot-types.ts"() {
|
|
5386
5399
|
init_logger();
|
|
5387
|
-
|
|
5400
|
+
slotLog2 = createLogger("almadar:ui:slot-render");
|
|
5388
5401
|
refIds = /* @__PURE__ */ new WeakMap();
|
|
5389
5402
|
nextRefId = 1;
|
|
5390
5403
|
}
|
|
@@ -46962,7 +46975,7 @@ function SlotContentRenderer({
|
|
|
46962
46975
|
}) {
|
|
46963
46976
|
const entityProp = content.props.entity;
|
|
46964
46977
|
if (content.pattern === "form-section") {
|
|
46965
|
-
|
|
46978
|
+
slotLog2.debug("SlotContentRenderer:form-section-render", {
|
|
46966
46979
|
contentId: content.id,
|
|
46967
46980
|
sourceTrait: content.sourceTrait,
|
|
46968
46981
|
entityRefId: refId(entityProp),
|
|
@@ -51711,6 +51724,7 @@ init_traitRegistry();
|
|
|
51711
51724
|
init_verificationRegistry();
|
|
51712
51725
|
var crossTraitLog = createLogger("almadar:ui:cross-trait");
|
|
51713
51726
|
var flushLog = createLogger("almadar:ui:slot-flush");
|
|
51727
|
+
var stateLog = createLogger("almadar:ui:state-transitions");
|
|
51714
51728
|
function toTraitDefinition(binding) {
|
|
51715
51729
|
return {
|
|
51716
51730
|
name: binding.trait.name,
|
|
@@ -52071,8 +52085,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52071
52085
|
payload: payload || {},
|
|
52072
52086
|
state: result.previousState
|
|
52073
52087
|
};
|
|
52074
|
-
|
|
52075
|
-
|
|
52088
|
+
const sharedDeclared = collectDeclaredConfigDefaults(
|
|
52089
|
+
binding.trait
|
|
52090
|
+
);
|
|
52091
|
+
const sharedCallSite = binding.config;
|
|
52092
|
+
if (sharedDeclared || sharedCallSite) {
|
|
52093
|
+
sharedBindings.config = {
|
|
52094
|
+
...sharedDeclared ?? {},
|
|
52095
|
+
...sharedCallSite ?? {}
|
|
52096
|
+
};
|
|
52076
52097
|
}
|
|
52077
52098
|
const serverHandlers = createServerEffectHandlers({
|
|
52078
52099
|
persistence,
|
|
@@ -52106,8 +52127,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52106
52127
|
payload: payload || {},
|
|
52107
52128
|
state: result.previousState
|
|
52108
52129
|
};
|
|
52109
|
-
|
|
52110
|
-
|
|
52130
|
+
const declaredDefaults = collectDeclaredConfigDefaults(
|
|
52131
|
+
binding.trait
|
|
52132
|
+
);
|
|
52133
|
+
const callSiteConfig = binding.config;
|
|
52134
|
+
if (declaredDefaults || callSiteConfig) {
|
|
52135
|
+
bindingCtx.config = {
|
|
52136
|
+
...declaredDefaults ?? {},
|
|
52137
|
+
...callSiteConfig ?? {}
|
|
52138
|
+
};
|
|
52111
52139
|
}
|
|
52112
52140
|
const effectContext = {
|
|
52113
52141
|
traitName: binding.trait.name,
|
|
@@ -52129,21 +52157,29 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52129
52157
|
const executor = new EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
52130
52158
|
try {
|
|
52131
52159
|
await executor.executeAll(result.effects);
|
|
52132
|
-
|
|
52133
|
-
|
|
52134
|
-
|
|
52135
|
-
|
|
52160
|
+
stateLog.info("transition:render-ui-dispatched", {
|
|
52161
|
+
traitName,
|
|
52162
|
+
fromState: result.previousState,
|
|
52163
|
+
toState: result.newState,
|
|
52164
|
+
event: eventKey,
|
|
52165
|
+
slotsTouched: Array.from(pendingSlots.keys()).join(","),
|
|
52166
|
+
patternTypes: Array.from(pendingSlots.entries()).map(
|
|
52167
|
+
([slot, patterns]) => `${slot}:[${patterns.map((p2) => p2.pattern?.type ?? "null").join(",")}]`
|
|
52168
|
+
).join(";")
|
|
52169
|
+
});
|
|
52136
52170
|
void slotSource;
|
|
52137
52171
|
for (const [slot, patterns] of pendingSlots) {
|
|
52138
52172
|
flushSlot(traitName, slot, patterns);
|
|
52139
52173
|
}
|
|
52140
52174
|
} catch (error) {
|
|
52141
|
-
|
|
52142
|
-
|
|
52143
|
-
|
|
52144
|
-
|
|
52145
|
-
|
|
52146
|
-
|
|
52175
|
+
stateLog.error("transition:effect-error", {
|
|
52176
|
+
traitName,
|
|
52177
|
+
fromState: result.previousState,
|
|
52178
|
+
toState: result.newState,
|
|
52179
|
+
event: eventKey,
|
|
52180
|
+
error: error instanceof Error ? error.message : String(error),
|
|
52181
|
+
effectCount: result.effects.length
|
|
52182
|
+
});
|
|
52147
52183
|
}
|
|
52148
52184
|
} else if (!result.executed) {
|
|
52149
52185
|
if (result.guardResult === false) {
|
|
@@ -52289,13 +52325,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52289
52325
|
if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
|
|
52290
52326
|
continue;
|
|
52291
52327
|
}
|
|
52292
|
-
const
|
|
52328
|
+
const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
|
|
52329
|
+
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
52330
|
+
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
52293
52331
|
if (event.source && event.source.fromBridge) {
|
|
52332
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
52294
52333
|
return;
|
|
52295
52334
|
}
|
|
52335
|
+
crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
52296
52336
|
enqueueAndDrain(eventKey, event.payload);
|
|
52297
52337
|
});
|
|
52298
|
-
unsubscribes.push(
|
|
52338
|
+
unsubscribes.push(() => {
|
|
52339
|
+
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
52340
|
+
unsub();
|
|
52341
|
+
});
|
|
52299
52342
|
}
|
|
52300
52343
|
}
|
|
52301
52344
|
for (const binding of traitBindings) {
|
|
@@ -52313,18 +52356,23 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
52313
52356
|
const sourceOrbital = listen.source?.orbital ?? ownOrbital;
|
|
52314
52357
|
if (!sourceOrbital) continue;
|
|
52315
52358
|
const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
|
|
52316
|
-
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
52359
|
+
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, sourceOrbital, sourceTrait, listenEvent: listen.event, triggers: listen.triggers });
|
|
52317
52360
|
const unsub = eventBus.on(busKey, (event) => {
|
|
52318
52361
|
crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
52319
52362
|
enqueueAndDrain(listen.triggers, event.payload);
|
|
52320
52363
|
});
|
|
52321
|
-
unsubscribes.push(
|
|
52364
|
+
unsubscribes.push(() => {
|
|
52365
|
+
crossTraitLog.debug("listen:unsubscribe", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
52366
|
+
unsub();
|
|
52367
|
+
});
|
|
52322
52368
|
}
|
|
52323
52369
|
}
|
|
52324
52370
|
return () => {
|
|
52371
|
+
crossTraitLog.debug("cleanup:start", { unsubscribeCount: unsubscribes.length });
|
|
52325
52372
|
for (const unsub of unsubscribes) {
|
|
52326
52373
|
unsub();
|
|
52327
52374
|
}
|
|
52375
|
+
crossTraitLog.debug("cleanup:done", {});
|
|
52328
52376
|
};
|
|
52329
52377
|
}, [traitBindings, eventBus, enqueueAndDrain]);
|
|
52330
52378
|
return {
|
|
@@ -40897,6 +40897,10 @@ function useDeepAgentGeneration() {
|
|
|
40897
40897
|
|
|
40898
40898
|
// hooks/index.ts
|
|
40899
40899
|
init_useEventBus();
|
|
40900
|
+
|
|
40901
|
+
// hooks/useUISlots.ts
|
|
40902
|
+
init_logger();
|
|
40903
|
+
var slotLog2 = createLogger("almadar:ui:useUISlots");
|
|
40900
40904
|
var DEFAULT_SOURCE_KEY = "__default__";
|
|
40901
40905
|
var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
40902
40906
|
var ALL_SLOTS2 = [
|
|
@@ -41055,6 +41059,13 @@ function useUISlotManager() {
|
|
|
41055
41059
|
indexTraitRender(content.sourceTrait, content);
|
|
41056
41060
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
41057
41061
|
}
|
|
41062
|
+
slotLog2.info("slot:written", {
|
|
41063
|
+
slot: config.target,
|
|
41064
|
+
sourceKey,
|
|
41065
|
+
sourceTrait: content.sourceTrait,
|
|
41066
|
+
patternType: content.pattern,
|
|
41067
|
+
priority: content.priority
|
|
41068
|
+
});
|
|
41058
41069
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
41059
41070
|
return nextAll;
|
|
41060
41071
|
});
|
|
@@ -41092,7 +41103,10 @@ function useUISlotManager() {
|
|
|
41092
41103
|
const sourceKey = sourceTrait;
|
|
41093
41104
|
setSources((prev) => {
|
|
41094
41105
|
const slotSources = prev[slot];
|
|
41095
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
41106
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
41107
|
+
slotLog2.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
41108
|
+
return prev;
|
|
41109
|
+
}
|
|
41096
41110
|
const content = slotSources[sourceKey];
|
|
41097
41111
|
const timer = timersRef.current.get(content.id);
|
|
41098
41112
|
if (timer) {
|
|
@@ -41106,6 +41120,7 @@ function useUISlotManager() {
|
|
|
41106
41120
|
}
|
|
41107
41121
|
const nextSources = { ...slotSources };
|
|
41108
41122
|
delete nextSources[sourceKey];
|
|
41123
|
+
slotLog2.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
41109
41124
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
41110
41125
|
return { ...prev, [slot]: nextSources };
|
|
41111
41126
|
});
|
package/dist/components/index.js
CHANGED
|
@@ -40852,6 +40852,10 @@ function useDeepAgentGeneration() {
|
|
|
40852
40852
|
|
|
40853
40853
|
// hooks/index.ts
|
|
40854
40854
|
init_useEventBus();
|
|
40855
|
+
|
|
40856
|
+
// hooks/useUISlots.ts
|
|
40857
|
+
init_logger();
|
|
40858
|
+
var slotLog2 = createLogger("almadar:ui:useUISlots");
|
|
40855
40859
|
var DEFAULT_SOURCE_KEY = "__default__";
|
|
40856
40860
|
var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
40857
40861
|
var ALL_SLOTS2 = [
|
|
@@ -41010,6 +41014,13 @@ function useUISlotManager() {
|
|
|
41010
41014
|
indexTraitRender(content.sourceTrait, content);
|
|
41011
41015
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
41012
41016
|
}
|
|
41017
|
+
slotLog2.info("slot:written", {
|
|
41018
|
+
slot: config.target,
|
|
41019
|
+
sourceKey,
|
|
41020
|
+
sourceTrait: content.sourceTrait,
|
|
41021
|
+
patternType: content.pattern,
|
|
41022
|
+
priority: content.priority
|
|
41023
|
+
});
|
|
41013
41024
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
41014
41025
|
return nextAll;
|
|
41015
41026
|
});
|
|
@@ -41047,7 +41058,10 @@ function useUISlotManager() {
|
|
|
41047
41058
|
const sourceKey = sourceTrait;
|
|
41048
41059
|
setSources((prev) => {
|
|
41049
41060
|
const slotSources = prev[slot];
|
|
41050
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
41061
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
41062
|
+
slotLog2.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
41063
|
+
return prev;
|
|
41064
|
+
}
|
|
41051
41065
|
const content = slotSources[sourceKey];
|
|
41052
41066
|
const timer = timersRef.current.get(content.id);
|
|
41053
41067
|
if (timer) {
|
|
@@ -41061,6 +41075,7 @@ function useUISlotManager() {
|
|
|
41061
41075
|
}
|
|
41062
41076
|
const nextSources = { ...slotSources };
|
|
41063
41077
|
delete nextSources[sourceKey];
|
|
41078
|
+
slotLog2.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
41064
41079
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
41065
41080
|
return { ...prev, [slot]: nextSources };
|
|
41066
41081
|
});
|
package/dist/context/index.cjs
CHANGED
|
@@ -3,6 +3,56 @@
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
|
|
6
|
+
// lib/logger.ts
|
|
7
|
+
var LEVEL_PRIORITY = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3 };
|
|
8
|
+
var ENV = typeof process !== "undefined" && process.env ? process.env : {};
|
|
9
|
+
function envGet(key) {
|
|
10
|
+
return ENV[key] ?? ENV[`VITE_${key}`];
|
|
11
|
+
}
|
|
12
|
+
var NODE_ENV = envGet("NODE_ENV") ?? "development";
|
|
13
|
+
var CONFIGURED_LEVEL = (envGet("LOG_LEVEL") ?? (NODE_ENV === "production" ? "info" : "debug")).toUpperCase();
|
|
14
|
+
var MIN_PRIORITY = LEVEL_PRIORITY[CONFIGURED_LEVEL] ?? 0;
|
|
15
|
+
var DEBUG_FILTER = (envGet("ALMADAR_DEBUG") ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
16
|
+
function matchesNamespace(namespace) {
|
|
17
|
+
if (DEBUG_FILTER.length === 0) return true;
|
|
18
|
+
return DEBUG_FILTER.some((pattern) => {
|
|
19
|
+
if (pattern === "*" || pattern === "almadar:*") return true;
|
|
20
|
+
if (pattern.endsWith(":*")) return namespace.startsWith(pattern.slice(0, -1));
|
|
21
|
+
return namespace === pattern;
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function createLogger(namespace) {
|
|
25
|
+
const nsAllowed = matchesNamespace(namespace);
|
|
26
|
+
const log = (level, message, data, correlationId) => {
|
|
27
|
+
if (LEVEL_PRIORITY[level] < MIN_PRIORITY) return;
|
|
28
|
+
if (level === "DEBUG" && !nsAllowed) return;
|
|
29
|
+
const prefix = `[${namespace}]`;
|
|
30
|
+
const logData = correlationId ? { ...data, cid: correlationId } : data;
|
|
31
|
+
switch (level) {
|
|
32
|
+
case "DEBUG":
|
|
33
|
+
console.debug(prefix, message, logData ?? "");
|
|
34
|
+
break;
|
|
35
|
+
case "INFO":
|
|
36
|
+
console.info(prefix, message, logData ?? "");
|
|
37
|
+
break;
|
|
38
|
+
case "WARN":
|
|
39
|
+
console.warn(prefix, message, logData ?? "");
|
|
40
|
+
break;
|
|
41
|
+
case "ERROR":
|
|
42
|
+
console.error(prefix, message, logData ?? "");
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
return {
|
|
47
|
+
debug: (msg, data, cid) => log("DEBUG", msg, data, cid),
|
|
48
|
+
info: (msg, data, cid) => log("INFO", msg, data, cid),
|
|
49
|
+
warn: (msg, data, cid) => log("WARN", msg, data, cid),
|
|
50
|
+
error: (msg, data, cid) => log("ERROR", msg, data, cid)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// hooks/useUISlots.ts
|
|
55
|
+
var slotLog = createLogger("almadar:ui:useUISlots");
|
|
6
56
|
var DEFAULT_SOURCE_KEY = "__default__";
|
|
7
57
|
var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
8
58
|
var ALL_SLOTS = [
|
|
@@ -161,6 +211,13 @@ function useUISlotManager() {
|
|
|
161
211
|
indexTraitRender(content.sourceTrait, content);
|
|
162
212
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
163
213
|
}
|
|
214
|
+
slotLog.info("slot:written", {
|
|
215
|
+
slot: config.target,
|
|
216
|
+
sourceKey,
|
|
217
|
+
sourceTrait: content.sourceTrait,
|
|
218
|
+
patternType: content.pattern,
|
|
219
|
+
priority: content.priority
|
|
220
|
+
});
|
|
164
221
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
165
222
|
return nextAll;
|
|
166
223
|
});
|
|
@@ -198,7 +255,10 @@ function useUISlotManager() {
|
|
|
198
255
|
const sourceKey = sourceTrait;
|
|
199
256
|
setSources((prev) => {
|
|
200
257
|
const slotSources = prev[slot];
|
|
201
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
258
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
259
|
+
slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
260
|
+
return prev;
|
|
261
|
+
}
|
|
202
262
|
const content = slotSources[sourceKey];
|
|
203
263
|
const timer = timersRef.current.get(content.id);
|
|
204
264
|
if (timer) {
|
|
@@ -212,6 +272,7 @@ function useUISlotManager() {
|
|
|
212
272
|
}
|
|
213
273
|
const nextSources = { ...slotSources };
|
|
214
274
|
delete nextSources[sourceKey];
|
|
275
|
+
slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
215
276
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
216
277
|
return { ...prev, [slot]: nextSources };
|
|
217
278
|
});
|
package/dist/context/index.js
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
import { createContext, useMemo, useContext, useState, useEffect, useCallback, useRef } from 'react';
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
|
+
// lib/logger.ts
|
|
5
|
+
var LEVEL_PRIORITY = { DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3 };
|
|
6
|
+
var ENV = typeof process !== "undefined" && process.env ? process.env : {};
|
|
7
|
+
function envGet(key) {
|
|
8
|
+
return ENV[key] ?? ENV[`VITE_${key}`];
|
|
9
|
+
}
|
|
10
|
+
var NODE_ENV = envGet("NODE_ENV") ?? "development";
|
|
11
|
+
var CONFIGURED_LEVEL = (envGet("LOG_LEVEL") ?? (NODE_ENV === "production" ? "info" : "debug")).toUpperCase();
|
|
12
|
+
var MIN_PRIORITY = LEVEL_PRIORITY[CONFIGURED_LEVEL] ?? 0;
|
|
13
|
+
var DEBUG_FILTER = (envGet("ALMADAR_DEBUG") ?? "").split(",").map((s) => s.trim()).filter(Boolean);
|
|
14
|
+
function matchesNamespace(namespace) {
|
|
15
|
+
if (DEBUG_FILTER.length === 0) return true;
|
|
16
|
+
return DEBUG_FILTER.some((pattern) => {
|
|
17
|
+
if (pattern === "*" || pattern === "almadar:*") return true;
|
|
18
|
+
if (pattern.endsWith(":*")) return namespace.startsWith(pattern.slice(0, -1));
|
|
19
|
+
return namespace === pattern;
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function createLogger(namespace) {
|
|
23
|
+
const nsAllowed = matchesNamespace(namespace);
|
|
24
|
+
const log = (level, message, data, correlationId) => {
|
|
25
|
+
if (LEVEL_PRIORITY[level] < MIN_PRIORITY) return;
|
|
26
|
+
if (level === "DEBUG" && !nsAllowed) return;
|
|
27
|
+
const prefix = `[${namespace}]`;
|
|
28
|
+
const logData = correlationId ? { ...data, cid: correlationId } : data;
|
|
29
|
+
switch (level) {
|
|
30
|
+
case "DEBUG":
|
|
31
|
+
console.debug(prefix, message, logData ?? "");
|
|
32
|
+
break;
|
|
33
|
+
case "INFO":
|
|
34
|
+
console.info(prefix, message, logData ?? "");
|
|
35
|
+
break;
|
|
36
|
+
case "WARN":
|
|
37
|
+
console.warn(prefix, message, logData ?? "");
|
|
38
|
+
break;
|
|
39
|
+
case "ERROR":
|
|
40
|
+
console.error(prefix, message, logData ?? "");
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return {
|
|
45
|
+
debug: (msg, data, cid) => log("DEBUG", msg, data, cid),
|
|
46
|
+
info: (msg, data, cid) => log("INFO", msg, data, cid),
|
|
47
|
+
warn: (msg, data, cid) => log("WARN", msg, data, cid),
|
|
48
|
+
error: (msg, data, cid) => log("ERROR", msg, data, cid)
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// hooks/useUISlots.ts
|
|
53
|
+
var slotLog = createLogger("almadar:ui:useUISlots");
|
|
4
54
|
var DEFAULT_SOURCE_KEY = "__default__";
|
|
5
55
|
var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
6
56
|
var ALL_SLOTS = [
|
|
@@ -159,6 +209,13 @@ function useUISlotManager() {
|
|
|
159
209
|
indexTraitRender(content.sourceTrait, content);
|
|
160
210
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
161
211
|
}
|
|
212
|
+
slotLog.info("slot:written", {
|
|
213
|
+
slot: config.target,
|
|
214
|
+
sourceKey,
|
|
215
|
+
sourceTrait: content.sourceTrait,
|
|
216
|
+
patternType: content.pattern,
|
|
217
|
+
priority: content.priority
|
|
218
|
+
});
|
|
162
219
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
163
220
|
return nextAll;
|
|
164
221
|
});
|
|
@@ -196,7 +253,10 @@ function useUISlotManager() {
|
|
|
196
253
|
const sourceKey = sourceTrait;
|
|
197
254
|
setSources((prev) => {
|
|
198
255
|
const slotSources = prev[slot];
|
|
199
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
256
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
257
|
+
slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
258
|
+
return prev;
|
|
259
|
+
}
|
|
200
260
|
const content = slotSources[sourceKey];
|
|
201
261
|
const timer = timersRef.current.get(content.id);
|
|
202
262
|
if (timer) {
|
|
@@ -210,6 +270,7 @@ function useUISlotManager() {
|
|
|
210
270
|
}
|
|
211
271
|
const nextSources = { ...slotSources };
|
|
212
272
|
delete nextSources[sourceKey];
|
|
273
|
+
slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
213
274
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
214
275
|
return { ...prev, [slot]: nextSources };
|
|
215
276
|
});
|
package/dist/hooks/index.cjs
CHANGED
|
@@ -1046,6 +1046,7 @@ function useEmitEvent() {
|
|
|
1046
1046
|
[eventBus]
|
|
1047
1047
|
);
|
|
1048
1048
|
}
|
|
1049
|
+
var slotLog = createLogger("almadar:ui:useUISlots");
|
|
1049
1050
|
var DEFAULT_SOURCE_KEY = "__default__";
|
|
1050
1051
|
var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
1051
1052
|
var ALL_SLOTS = [
|
|
@@ -1204,6 +1205,13 @@ function useUISlotManager() {
|
|
|
1204
1205
|
indexTraitRender(content.sourceTrait, content);
|
|
1205
1206
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
1206
1207
|
}
|
|
1208
|
+
slotLog.info("slot:written", {
|
|
1209
|
+
slot: config.target,
|
|
1210
|
+
sourceKey,
|
|
1211
|
+
sourceTrait: content.sourceTrait,
|
|
1212
|
+
patternType: content.pattern,
|
|
1213
|
+
priority: content.priority
|
|
1214
|
+
});
|
|
1207
1215
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
1208
1216
|
return nextAll;
|
|
1209
1217
|
});
|
|
@@ -1241,7 +1249,10 @@ function useUISlotManager() {
|
|
|
1241
1249
|
const sourceKey = sourceTrait;
|
|
1242
1250
|
setSources((prev) => {
|
|
1243
1251
|
const slotSources = prev[slot];
|
|
1244
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
1252
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
1253
|
+
slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
1254
|
+
return prev;
|
|
1255
|
+
}
|
|
1245
1256
|
const content = slotSources[sourceKey];
|
|
1246
1257
|
const timer = timersRef.current.get(content.id);
|
|
1247
1258
|
if (timer) {
|
|
@@ -1255,6 +1266,7 @@ function useUISlotManager() {
|
|
|
1255
1266
|
}
|
|
1256
1267
|
const nextSources = { ...slotSources };
|
|
1257
1268
|
delete nextSources[sourceKey];
|
|
1269
|
+
slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
1258
1270
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
1259
1271
|
return { ...prev, [slot]: nextSources };
|
|
1260
1272
|
});
|
package/dist/hooks/index.js
CHANGED
|
@@ -1044,6 +1044,7 @@ function useEmitEvent() {
|
|
|
1044
1044
|
[eventBus]
|
|
1045
1045
|
);
|
|
1046
1046
|
}
|
|
1047
|
+
var slotLog = createLogger("almadar:ui:useUISlots");
|
|
1047
1048
|
var DEFAULT_SOURCE_KEY = "__default__";
|
|
1048
1049
|
var MULTI_SOURCE_STACK_TRAIT = "__multi_source_stack__";
|
|
1049
1050
|
var ALL_SLOTS = [
|
|
@@ -1202,6 +1203,13 @@ function useUISlotManager() {
|
|
|
1202
1203
|
indexTraitRender(content.sourceTrait, content);
|
|
1203
1204
|
notifyTraitSubscribers(content.sourceTrait, content);
|
|
1204
1205
|
}
|
|
1206
|
+
slotLog.info("slot:written", {
|
|
1207
|
+
slot: config.target,
|
|
1208
|
+
sourceKey,
|
|
1209
|
+
sourceTrait: content.sourceTrait,
|
|
1210
|
+
patternType: content.pattern,
|
|
1211
|
+
priority: content.priority
|
|
1212
|
+
});
|
|
1205
1213
|
notifySubscribers(config.target, aggregateSlot(nextSources));
|
|
1206
1214
|
return nextAll;
|
|
1207
1215
|
});
|
|
@@ -1239,7 +1247,10 @@ function useUISlotManager() {
|
|
|
1239
1247
|
const sourceKey = sourceTrait;
|
|
1240
1248
|
setSources((prev) => {
|
|
1241
1249
|
const slotSources = prev[slot];
|
|
1242
|
-
if (!slotSources || !(sourceKey in slotSources))
|
|
1250
|
+
if (!slotSources || !(sourceKey in slotSources)) {
|
|
1251
|
+
slotLog.debug("slot:clear-noop", { slot, sourceTrait, reason: !slotSources ? "no-slot" : "no-source" });
|
|
1252
|
+
return prev;
|
|
1253
|
+
}
|
|
1243
1254
|
const content = slotSources[sourceKey];
|
|
1244
1255
|
const timer = timersRef.current.get(content.id);
|
|
1245
1256
|
if (timer) {
|
|
@@ -1253,6 +1264,7 @@ function useUISlotManager() {
|
|
|
1253
1264
|
}
|
|
1254
1265
|
const nextSources = { ...slotSources };
|
|
1255
1266
|
delete nextSources[sourceKey];
|
|
1267
|
+
slotLog.info("slot:cleared", { slot, sourceTrait, lastPatternType: content.pattern });
|
|
1256
1268
|
notifySubscribers(slot, aggregateSlot(nextSources));
|
|
1257
1269
|
return { ...prev, [slot]: nextSources };
|
|
1258
1270
|
});
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -2086,11 +2086,11 @@ function refId(obj) {
|
|
|
2086
2086
|
refIds.set(obj, id);
|
|
2087
2087
|
return id;
|
|
2088
2088
|
}
|
|
2089
|
-
var
|
|
2089
|
+
var slotLog2, refIds, nextRefId;
|
|
2090
2090
|
var init_slot_types = __esm({
|
|
2091
2091
|
"runtime/ui/slot-types.ts"() {
|
|
2092
2092
|
init_logger();
|
|
2093
|
-
|
|
2093
|
+
slotLog2 = createLogger("almadar:ui:slot-render");
|
|
2094
2094
|
refIds = /* @__PURE__ */ new WeakMap();
|
|
2095
2095
|
nextRefId = 1;
|
|
2096
2096
|
}
|
|
@@ -37880,7 +37880,7 @@ function SlotContentRenderer({
|
|
|
37880
37880
|
}) {
|
|
37881
37881
|
const entityProp = content.props.entity;
|
|
37882
37882
|
if (content.pattern === "form-section") {
|
|
37883
|
-
|
|
37883
|
+
slotLog2.debug("SlotContentRenderer:form-section-render", {
|
|
37884
37884
|
contentId: content.id,
|
|
37885
37885
|
sourceTrait: content.sourceTrait,
|
|
37886
37886
|
entityRefId: refId(entityProp),
|
|
@@ -38091,6 +38091,10 @@ var init_UISlotRenderer = __esm({
|
|
|
38091
38091
|
|
|
38092
38092
|
// hooks/index.ts
|
|
38093
38093
|
init_useEventBus();
|
|
38094
|
+
|
|
38095
|
+
// hooks/useUISlots.ts
|
|
38096
|
+
init_logger();
|
|
38097
|
+
createLogger("almadar:ui:useUISlots");
|
|
38094
38098
|
var ALL_SLOTS = [
|
|
38095
38099
|
"main",
|
|
38096
38100
|
"sidebar",
|
|
@@ -38293,6 +38297,7 @@ init_traitRegistry();
|
|
|
38293
38297
|
init_verificationRegistry();
|
|
38294
38298
|
var crossTraitLog = createLogger("almadar:ui:cross-trait");
|
|
38295
38299
|
var flushLog = createLogger("almadar:ui:slot-flush");
|
|
38300
|
+
var stateLog = createLogger("almadar:ui:state-transitions");
|
|
38296
38301
|
function toTraitDefinition(binding) {
|
|
38297
38302
|
return {
|
|
38298
38303
|
name: binding.trait.name,
|
|
@@ -38653,8 +38658,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38653
38658
|
payload: payload || {},
|
|
38654
38659
|
state: result.previousState
|
|
38655
38660
|
};
|
|
38656
|
-
|
|
38657
|
-
|
|
38661
|
+
const sharedDeclared = runtime.collectDeclaredConfigDefaults(
|
|
38662
|
+
binding.trait
|
|
38663
|
+
);
|
|
38664
|
+
const sharedCallSite = binding.config;
|
|
38665
|
+
if (sharedDeclared || sharedCallSite) {
|
|
38666
|
+
sharedBindings.config = {
|
|
38667
|
+
...sharedDeclared ?? {},
|
|
38668
|
+
...sharedCallSite ?? {}
|
|
38669
|
+
};
|
|
38658
38670
|
}
|
|
38659
38671
|
const serverHandlers = runtime.createServerEffectHandlers({
|
|
38660
38672
|
persistence,
|
|
@@ -38688,8 +38700,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38688
38700
|
payload: payload || {},
|
|
38689
38701
|
state: result.previousState
|
|
38690
38702
|
};
|
|
38691
|
-
|
|
38692
|
-
|
|
38703
|
+
const declaredDefaults = runtime.collectDeclaredConfigDefaults(
|
|
38704
|
+
binding.trait
|
|
38705
|
+
);
|
|
38706
|
+
const callSiteConfig = binding.config;
|
|
38707
|
+
if (declaredDefaults || callSiteConfig) {
|
|
38708
|
+
bindingCtx.config = {
|
|
38709
|
+
...declaredDefaults ?? {},
|
|
38710
|
+
...callSiteConfig ?? {}
|
|
38711
|
+
};
|
|
38693
38712
|
}
|
|
38694
38713
|
const effectContext = {
|
|
38695
38714
|
traitName: binding.trait.name,
|
|
@@ -38711,21 +38730,29 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38711
38730
|
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
38712
38731
|
try {
|
|
38713
38732
|
await executor.executeAll(result.effects);
|
|
38714
|
-
|
|
38715
|
-
|
|
38716
|
-
|
|
38717
|
-
|
|
38733
|
+
stateLog.info("transition:render-ui-dispatched", {
|
|
38734
|
+
traitName,
|
|
38735
|
+
fromState: result.previousState,
|
|
38736
|
+
toState: result.newState,
|
|
38737
|
+
event: eventKey,
|
|
38738
|
+
slotsTouched: Array.from(pendingSlots.keys()).join(","),
|
|
38739
|
+
patternTypes: Array.from(pendingSlots.entries()).map(
|
|
38740
|
+
([slot, patterns]) => `${slot}:[${patterns.map((p2) => p2.pattern?.type ?? "null").join(",")}]`
|
|
38741
|
+
).join(";")
|
|
38742
|
+
});
|
|
38718
38743
|
void slotSource;
|
|
38719
38744
|
for (const [slot, patterns] of pendingSlots) {
|
|
38720
38745
|
flushSlot(traitName, slot, patterns);
|
|
38721
38746
|
}
|
|
38722
38747
|
} catch (error) {
|
|
38723
|
-
|
|
38724
|
-
|
|
38725
|
-
|
|
38726
|
-
|
|
38727
|
-
|
|
38728
|
-
|
|
38748
|
+
stateLog.error("transition:effect-error", {
|
|
38749
|
+
traitName,
|
|
38750
|
+
fromState: result.previousState,
|
|
38751
|
+
toState: result.newState,
|
|
38752
|
+
event: eventKey,
|
|
38753
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38754
|
+
effectCount: result.effects.length
|
|
38755
|
+
});
|
|
38729
38756
|
}
|
|
38730
38757
|
} else if (!result.executed) {
|
|
38731
38758
|
if (result.guardResult === false) {
|
|
@@ -38871,13 +38898,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38871
38898
|
if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
|
|
38872
38899
|
continue;
|
|
38873
38900
|
}
|
|
38874
|
-
const
|
|
38901
|
+
const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
|
|
38902
|
+
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
38903
|
+
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
38875
38904
|
if (event.source && event.source.fromBridge) {
|
|
38905
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
38876
38906
|
return;
|
|
38877
38907
|
}
|
|
38908
|
+
crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
38878
38909
|
enqueueAndDrain(eventKey, event.payload);
|
|
38879
38910
|
});
|
|
38880
|
-
unsubscribes.push(
|
|
38911
|
+
unsubscribes.push(() => {
|
|
38912
|
+
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
38913
|
+
unsub();
|
|
38914
|
+
});
|
|
38881
38915
|
}
|
|
38882
38916
|
}
|
|
38883
38917
|
for (const binding of traitBindings) {
|
|
@@ -38895,18 +38929,23 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38895
38929
|
const sourceOrbital = listen.source?.orbital ?? ownOrbital;
|
|
38896
38930
|
if (!sourceOrbital) continue;
|
|
38897
38931
|
const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
|
|
38898
|
-
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
38932
|
+
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, sourceOrbital, sourceTrait, listenEvent: listen.event, triggers: listen.triggers });
|
|
38899
38933
|
const unsub = eventBus.on(busKey, (event) => {
|
|
38900
38934
|
crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
38901
38935
|
enqueueAndDrain(listen.triggers, event.payload);
|
|
38902
38936
|
});
|
|
38903
|
-
unsubscribes.push(
|
|
38937
|
+
unsubscribes.push(() => {
|
|
38938
|
+
crossTraitLog.debug("listen:unsubscribe", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
38939
|
+
unsub();
|
|
38940
|
+
});
|
|
38904
38941
|
}
|
|
38905
38942
|
}
|
|
38906
38943
|
return () => {
|
|
38944
|
+
crossTraitLog.debug("cleanup:start", { unsubscribeCount: unsubscribes.length });
|
|
38907
38945
|
for (const unsub of unsubscribes) {
|
|
38908
38946
|
unsub();
|
|
38909
38947
|
}
|
|
38948
|
+
crossTraitLog.debug("cleanup:done", {});
|
|
38910
38949
|
};
|
|
38911
38950
|
}, [traitBindings, eventBus, enqueueAndDrain]);
|
|
38912
38951
|
return {
|
package/dist/runtime/index.js
CHANGED
|
@@ -36,7 +36,7 @@ import langGo from 'react-syntax-highlighter/dist/esm/languages/prism/go.js';
|
|
|
36
36
|
import langGraphql from 'react-syntax-highlighter/dist/esm/languages/prism/graphql.js';
|
|
37
37
|
import { isCircuitEvent, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, isEntityCall, isInlineTrait } from '@almadar/core';
|
|
38
38
|
import '@tanstack/react-query';
|
|
39
|
-
import { StateMachineManager, createContextFromBindings, interpolateValue, createServerEffectHandlers, EffectExecutor, InMemoryPersistence } from '@almadar/runtime';
|
|
39
|
+
import { StateMachineManager, createContextFromBindings, interpolateValue, collectDeclaredConfigDefaults, createServerEffectHandlers, EffectExecutor, InMemoryPersistence } from '@almadar/runtime';
|
|
40
40
|
import { OrbitalServerRuntime } from '@almadar/runtime/OrbitalServerRuntime';
|
|
41
41
|
|
|
42
42
|
var __defProp = Object.defineProperty;
|
|
@@ -2041,11 +2041,11 @@ function refId(obj) {
|
|
|
2041
2041
|
refIds.set(obj, id);
|
|
2042
2042
|
return id;
|
|
2043
2043
|
}
|
|
2044
|
-
var
|
|
2044
|
+
var slotLog2, refIds, nextRefId;
|
|
2045
2045
|
var init_slot_types = __esm({
|
|
2046
2046
|
"runtime/ui/slot-types.ts"() {
|
|
2047
2047
|
init_logger();
|
|
2048
|
-
|
|
2048
|
+
slotLog2 = createLogger("almadar:ui:slot-render");
|
|
2049
2049
|
refIds = /* @__PURE__ */ new WeakMap();
|
|
2050
2050
|
nextRefId = 1;
|
|
2051
2051
|
}
|
|
@@ -37835,7 +37835,7 @@ function SlotContentRenderer({
|
|
|
37835
37835
|
}) {
|
|
37836
37836
|
const entityProp = content.props.entity;
|
|
37837
37837
|
if (content.pattern === "form-section") {
|
|
37838
|
-
|
|
37838
|
+
slotLog2.debug("SlotContentRenderer:form-section-render", {
|
|
37839
37839
|
contentId: content.id,
|
|
37840
37840
|
sourceTrait: content.sourceTrait,
|
|
37841
37841
|
entityRefId: refId(entityProp),
|
|
@@ -38046,6 +38046,10 @@ var init_UISlotRenderer = __esm({
|
|
|
38046
38046
|
|
|
38047
38047
|
// hooks/index.ts
|
|
38048
38048
|
init_useEventBus();
|
|
38049
|
+
|
|
38050
|
+
// hooks/useUISlots.ts
|
|
38051
|
+
init_logger();
|
|
38052
|
+
createLogger("almadar:ui:useUISlots");
|
|
38049
38053
|
var ALL_SLOTS = [
|
|
38050
38054
|
"main",
|
|
38051
38055
|
"sidebar",
|
|
@@ -38248,6 +38252,7 @@ init_traitRegistry();
|
|
|
38248
38252
|
init_verificationRegistry();
|
|
38249
38253
|
var crossTraitLog = createLogger("almadar:ui:cross-trait");
|
|
38250
38254
|
var flushLog = createLogger("almadar:ui:slot-flush");
|
|
38255
|
+
var stateLog = createLogger("almadar:ui:state-transitions");
|
|
38251
38256
|
function toTraitDefinition(binding) {
|
|
38252
38257
|
return {
|
|
38253
38258
|
name: binding.trait.name,
|
|
@@ -38608,8 +38613,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38608
38613
|
payload: payload || {},
|
|
38609
38614
|
state: result.previousState
|
|
38610
38615
|
};
|
|
38611
|
-
|
|
38612
|
-
|
|
38616
|
+
const sharedDeclared = collectDeclaredConfigDefaults(
|
|
38617
|
+
binding.trait
|
|
38618
|
+
);
|
|
38619
|
+
const sharedCallSite = binding.config;
|
|
38620
|
+
if (sharedDeclared || sharedCallSite) {
|
|
38621
|
+
sharedBindings.config = {
|
|
38622
|
+
...sharedDeclared ?? {},
|
|
38623
|
+
...sharedCallSite ?? {}
|
|
38624
|
+
};
|
|
38613
38625
|
}
|
|
38614
38626
|
const serverHandlers = createServerEffectHandlers({
|
|
38615
38627
|
persistence,
|
|
@@ -38643,8 +38655,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38643
38655
|
payload: payload || {},
|
|
38644
38656
|
state: result.previousState
|
|
38645
38657
|
};
|
|
38646
|
-
|
|
38647
|
-
|
|
38658
|
+
const declaredDefaults = collectDeclaredConfigDefaults(
|
|
38659
|
+
binding.trait
|
|
38660
|
+
);
|
|
38661
|
+
const callSiteConfig = binding.config;
|
|
38662
|
+
if (declaredDefaults || callSiteConfig) {
|
|
38663
|
+
bindingCtx.config = {
|
|
38664
|
+
...declaredDefaults ?? {},
|
|
38665
|
+
...callSiteConfig ?? {}
|
|
38666
|
+
};
|
|
38648
38667
|
}
|
|
38649
38668
|
const effectContext = {
|
|
38650
38669
|
traitName: binding.trait.name,
|
|
@@ -38666,21 +38685,29 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38666
38685
|
const executor = new EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
38667
38686
|
try {
|
|
38668
38687
|
await executor.executeAll(result.effects);
|
|
38669
|
-
|
|
38670
|
-
|
|
38671
|
-
|
|
38672
|
-
|
|
38688
|
+
stateLog.info("transition:render-ui-dispatched", {
|
|
38689
|
+
traitName,
|
|
38690
|
+
fromState: result.previousState,
|
|
38691
|
+
toState: result.newState,
|
|
38692
|
+
event: eventKey,
|
|
38693
|
+
slotsTouched: Array.from(pendingSlots.keys()).join(","),
|
|
38694
|
+
patternTypes: Array.from(pendingSlots.entries()).map(
|
|
38695
|
+
([slot, patterns]) => `${slot}:[${patterns.map((p2) => p2.pattern?.type ?? "null").join(",")}]`
|
|
38696
|
+
).join(";")
|
|
38697
|
+
});
|
|
38673
38698
|
void slotSource;
|
|
38674
38699
|
for (const [slot, patterns] of pendingSlots) {
|
|
38675
38700
|
flushSlot(traitName, slot, patterns);
|
|
38676
38701
|
}
|
|
38677
38702
|
} catch (error) {
|
|
38678
|
-
|
|
38679
|
-
|
|
38680
|
-
|
|
38681
|
-
|
|
38682
|
-
|
|
38683
|
-
|
|
38703
|
+
stateLog.error("transition:effect-error", {
|
|
38704
|
+
traitName,
|
|
38705
|
+
fromState: result.previousState,
|
|
38706
|
+
toState: result.newState,
|
|
38707
|
+
event: eventKey,
|
|
38708
|
+
error: error instanceof Error ? error.message : String(error),
|
|
38709
|
+
effectCount: result.effects.length
|
|
38710
|
+
});
|
|
38684
38711
|
}
|
|
38685
38712
|
} else if (!result.executed) {
|
|
38686
38713
|
if (result.guardResult === false) {
|
|
@@ -38826,13 +38853,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38826
38853
|
if (eventKey === "INIT" || eventKey === "LOAD" || eventKey === "$MOUNT") {
|
|
38827
38854
|
continue;
|
|
38828
38855
|
}
|
|
38829
|
-
const
|
|
38856
|
+
const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
|
|
38857
|
+
crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
38858
|
+
const unsub = eventBus.on(selfBusKey, (event) => {
|
|
38830
38859
|
if (event.source && event.source.fromBridge) {
|
|
38860
|
+
crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
|
|
38831
38861
|
return;
|
|
38832
38862
|
}
|
|
38863
|
+
crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
|
|
38833
38864
|
enqueueAndDrain(eventKey, event.payload);
|
|
38834
38865
|
});
|
|
38835
|
-
unsubscribes.push(
|
|
38866
|
+
unsubscribes.push(() => {
|
|
38867
|
+
crossTraitLog.debug("self:unsubscribe", { traitName, busKey: selfBusKey, eventKey });
|
|
38868
|
+
unsub();
|
|
38869
|
+
});
|
|
38836
38870
|
}
|
|
38837
38871
|
}
|
|
38838
38872
|
for (const binding of traitBindings) {
|
|
@@ -38850,18 +38884,23 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
38850
38884
|
const sourceOrbital = listen.source?.orbital ?? ownOrbital;
|
|
38851
38885
|
if (!sourceOrbital) continue;
|
|
38852
38886
|
const busKey = `UI:${sourceOrbital}.${sourceTrait}.${listen.event}`;
|
|
38853
|
-
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
38887
|
+
crossTraitLog.debug("listen:subscribed", { busKey, targetTrait: binding.trait.name, sourceOrbital, sourceTrait, listenEvent: listen.event, triggers: listen.triggers });
|
|
38854
38888
|
const unsub = eventBus.on(busKey, (event) => {
|
|
38855
38889
|
crossTraitLog.info("listen:fired", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
38856
38890
|
enqueueAndDrain(listen.triggers, event.payload);
|
|
38857
38891
|
});
|
|
38858
|
-
unsubscribes.push(
|
|
38892
|
+
unsubscribes.push(() => {
|
|
38893
|
+
crossTraitLog.debug("listen:unsubscribe", { busKey, targetTrait: binding.trait.name, triggers: listen.triggers });
|
|
38894
|
+
unsub();
|
|
38895
|
+
});
|
|
38859
38896
|
}
|
|
38860
38897
|
}
|
|
38861
38898
|
return () => {
|
|
38899
|
+
crossTraitLog.debug("cleanup:start", { unsubscribeCount: unsubscribes.length });
|
|
38862
38900
|
for (const unsub of unsubscribes) {
|
|
38863
38901
|
unsub();
|
|
38864
38902
|
}
|
|
38903
|
+
crossTraitLog.debug("cleanup:done", {});
|
|
38865
38904
|
};
|
|
38866
38905
|
}, [traitBindings, eventBus, enqueueAndDrain]);
|
|
38867
38906
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "4.15.
|
|
3
|
+
"version": "4.15.5",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/components/index.js",
|
|
@@ -118,10 +118,10 @@
|
|
|
118
118
|
"access": "public"
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
|
-
"@almadar/core": "^7.
|
|
121
|
+
"@almadar/core": "^7.5.1",
|
|
122
122
|
"@almadar/evaluator": ">=2.9.2",
|
|
123
123
|
"@almadar/patterns": ">=2.17.1",
|
|
124
|
-
"@almadar/runtime": "^5.
|
|
124
|
+
"@almadar/runtime": "^5.8.4",
|
|
125
125
|
"@almadar/std": ">=6.4.1",
|
|
126
126
|
"@almadar/syntax": ">=1.3.1",
|
|
127
127
|
"@xyflow/react": "12.10.1",
|