@almadar/ui 5.101.0 → 5.104.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 +253 -49
- package/dist/avl/index.css +3 -3
- package/dist/avl/index.js +255 -51
- package/dist/components/core/atoms/AtlasImage.d.ts +2 -2
- package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
- package/dist/components/core/molecules/Card.d.ts +1 -1
- package/dist/components/core/molecules/Chart.d.ts +3 -3
- package/dist/components/core/molecules/DataGrid.d.ts +1 -1
- package/dist/components/core/molecules/DataList.d.ts +1 -1
- package/dist/components/core/molecules/DocPagination.d.ts +8 -1
- package/dist/components/core/molecules/DocSearch.d.ts +8 -1
- package/dist/components/core/molecules/FlipCard.d.ts +1 -1
- package/dist/components/core/molecules/LineChart.d.ts +3 -1
- package/dist/components/core/molecules/MapView.d.ts +18 -1
- package/dist/components/core/molecules/SortableList.d.ts +1 -1
- package/dist/components/core/molecules/TableView.d.ts +1 -1
- package/dist/components/core/organisms/DataTable.d.ts +7 -3
- package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +10 -1
- package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +2 -1
- package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
- package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +6 -1
- package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +6 -1
- package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +12 -1
- package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +2 -1
- package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +2 -1
- package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +11 -1
- package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +8 -1
- package/dist/components/game/2d/atoms/ActionButton.d.ts +2 -1
- package/dist/components/game/2d/atoms/ChoiceButton.d.ts +2 -1
- package/dist/components/game/2d/atoms/ComboCounter.d.ts +2 -1
- package/dist/components/game/2d/atoms/ControlButton.d.ts +2 -1
- package/dist/components/game/2d/atoms/DamageNumber.d.ts +2 -1
- package/dist/components/game/2d/atoms/DialogueBubble.d.ts +2 -1
- package/dist/components/game/2d/atoms/GameIcon.d.ts +2 -1
- package/dist/components/game/2d/atoms/HealthBar.d.ts +2 -1
- package/dist/components/game/2d/atoms/ItemSlot.d.ts +2 -1
- package/dist/components/game/2d/atoms/MiniMap.d.ts +2 -1
- package/dist/components/game/2d/atoms/ResourceCounter.d.ts +2 -1
- package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +2 -1
- package/dist/components/game/2d/atoms/StatusEffect.d.ts +2 -1
- package/dist/components/game/2d/atoms/TimerDisplay.d.ts +2 -1
- package/dist/components/game/2d/atoms/TurnIndicator.d.ts +2 -1
- package/dist/components/game/2d/atoms/WaypointMarker.d.ts +2 -1
- package/dist/components/game/2d/molecules/Canvas2D.d.ts +5 -4
- package/dist/components/game/2d/molecules/GameHud.d.ts +2 -1
- package/dist/components/game/2d/molecules/GameMenu.d.ts +2 -1
- package/dist/components/game/2d/molecules/InventoryGrid.d.ts +2 -1
- package/dist/components/game/2d/molecules/ResourceBar.d.ts +2 -1
- package/dist/components/game/2d/molecules/StatBadge.d.ts +2 -1
- package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
- package/dist/components/index.cjs +100 -24
- package/dist/components/index.css +3 -3
- package/dist/components/index.js +85 -13
- package/dist/hooks/index.cjs +71 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +69 -2
- package/dist/hooks/useGitHub.d.ts +7 -7
- package/dist/hooks/useSharedEntityStore.d.ts +53 -0
- package/dist/hooks/useTraitStateMachine.d.ts +32 -1
- package/dist/marketing/index.cjs +2 -2
- package/dist/marketing/index.js +2 -2
- package/dist/providers/EventBusProvider.d.ts +1 -1
- package/dist/providers/SelectionProvider.d.ts +1 -1
- package/dist/providers/ServerBridge.d.ts +1 -1
- package/dist/providers/index.cjs +11 -5
- package/dist/providers/index.css +3 -3
- package/dist/providers/index.js +11 -5
- package/dist/runtime/index.cjs +253 -49
- package/dist/runtime/index.css +3 -3
- package/dist/runtime/index.js +255 -51
- package/package.json +11 -16
package/dist/avl/index.cjs
CHANGED
|
@@ -630,7 +630,7 @@ var init_AvlFieldType = __esm({
|
|
|
630
630
|
}
|
|
631
631
|
});
|
|
632
632
|
|
|
633
|
-
// node_modules/clsx/dist/clsx.mjs
|
|
633
|
+
// node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
|
|
634
634
|
function r(e) {
|
|
635
635
|
var t, f3, n = "";
|
|
636
636
|
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
@@ -645,11 +645,11 @@ function clsx() {
|
|
|
645
645
|
return n;
|
|
646
646
|
}
|
|
647
647
|
var init_clsx = __esm({
|
|
648
|
-
"node_modules/clsx/dist/clsx.mjs"() {
|
|
648
|
+
"node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs"() {
|
|
649
649
|
}
|
|
650
650
|
});
|
|
651
651
|
|
|
652
|
-
// node_modules/tailwind-merge/dist/bundle-mjs.mjs
|
|
652
|
+
// node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
|
|
653
653
|
function twJoin() {
|
|
654
654
|
let index = 0;
|
|
655
655
|
let argument;
|
|
@@ -693,7 +693,7 @@ function createTailwindMerge(createConfigFirst, ...createConfigRest) {
|
|
|
693
693
|
}
|
|
694
694
|
var CLASS_PART_SEPARATOR, createClassGroupUtils, getGroupRecursive, arbitraryPropertyRegex, getGroupIdForArbitraryProperty, createClassMap, processClassesRecursively, getPart, isThemeGetter, getPrefixedClassGroupEntries, createLruCache, IMPORTANT_MODIFIER, createParseClassName, sortModifiers, createConfigUtils, SPLIT_CLASSES_REGEX, mergeClassList, toValue, fromTheme, arbitraryValueRegex, fractionRegex, stringLengths, tshirtUnitRegex, lengthUnitRegex, colorFunctionRegex, shadowRegex, imageRegex, isLength, isArbitraryLength, isNumber, isArbitraryNumber, isInteger, isPercent, isArbitraryValue, isTshirtSize, sizeLabels, isArbitrarySize, isArbitraryPosition, imageLabels, isArbitraryImage, isArbitraryShadow, isAny, getIsArbitraryValue, isLengthOnly, isNever, isShadow, isImage, getDefaultConfig, twMerge;
|
|
695
695
|
var init_bundle_mjs = __esm({
|
|
696
|
-
"node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
|
|
696
|
+
"node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs"() {
|
|
697
697
|
CLASS_PART_SEPARATOR = "-";
|
|
698
698
|
createClassGroupUtils = (config) => {
|
|
699
699
|
const classMap = createClassMap(config);
|
|
@@ -14003,6 +14003,9 @@ var init_useUnitSpriteAtlas = __esm({
|
|
|
14003
14003
|
init_spriteAnimation();
|
|
14004
14004
|
}
|
|
14005
14005
|
});
|
|
14006
|
+
function normalizeBackdrop(bg) {
|
|
14007
|
+
return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
|
|
14008
|
+
}
|
|
14006
14009
|
function SideView({
|
|
14007
14010
|
player,
|
|
14008
14011
|
platforms,
|
|
@@ -14012,7 +14015,7 @@ function SideView({
|
|
|
14012
14015
|
canvasHeight,
|
|
14013
14016
|
follow,
|
|
14014
14017
|
bgColor,
|
|
14015
|
-
backgroundImage,
|
|
14018
|
+
backgroundImage: backgroundImageRaw,
|
|
14016
14019
|
playerSprite,
|
|
14017
14020
|
tileSprites,
|
|
14018
14021
|
effects,
|
|
@@ -14020,6 +14023,7 @@ function SideView({
|
|
|
14020
14023
|
keyUpMap,
|
|
14021
14024
|
className
|
|
14022
14025
|
}) {
|
|
14026
|
+
const backgroundImage = normalizeBackdrop(backgroundImageRaw);
|
|
14023
14027
|
const canvasRef = React105.useRef(null);
|
|
14024
14028
|
const eventBus = useEventBus();
|
|
14025
14029
|
const keysRef = React105.useRef(/* @__PURE__ */ new Set());
|
|
@@ -14311,7 +14315,7 @@ function Canvas2D({
|
|
|
14311
14315
|
effects: _effectsPropRaw = [],
|
|
14312
14316
|
platforms,
|
|
14313
14317
|
player,
|
|
14314
|
-
backgroundImage,
|
|
14318
|
+
backgroundImage: backgroundImageRaw,
|
|
14315
14319
|
// Interaction state
|
|
14316
14320
|
selectedUnitId = null,
|
|
14317
14321
|
validMoves = [],
|
|
@@ -14352,6 +14356,7 @@ function Canvas2D({
|
|
|
14352
14356
|
// Remote asset loading
|
|
14353
14357
|
assetManifest
|
|
14354
14358
|
}) {
|
|
14359
|
+
const backgroundImage = normalizeBackdrop(backgroundImageRaw);
|
|
14355
14360
|
const isSide = projection === "side";
|
|
14356
14361
|
const isFree = projection === "free";
|
|
14357
14362
|
const flatLike = projection === "hex" || projection === "flat" || isFree;
|
|
@@ -20335,9 +20340,9 @@ var init_BiologyCanvas = __esm({
|
|
|
20335
20340
|
}
|
|
20336
20341
|
});
|
|
20337
20342
|
|
|
20338
|
-
// node_modules/katex/dist/katex.min.css
|
|
20343
|
+
// node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
|
|
20339
20344
|
var init_katex_min = __esm({
|
|
20340
|
-
"node_modules/katex/dist/katex.min.css"() {
|
|
20345
|
+
"node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
|
|
20341
20346
|
}
|
|
20342
20347
|
});
|
|
20343
20348
|
var Tabs;
|
|
@@ -32543,8 +32548,9 @@ var init_LineChart = __esm({
|
|
|
32543
32548
|
const safeData = data ?? [];
|
|
32544
32549
|
const sortedData = React105.useMemo(() => {
|
|
32545
32550
|
if (safeData.length === 0) return [];
|
|
32551
|
+
if (!safeData.some((d) => d.date != null)) return [...safeData];
|
|
32546
32552
|
return [...safeData].sort(
|
|
32547
|
-
(a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
|
|
32553
|
+
(a, b) => new Date(a.date ?? 0).getTime() - new Date(b.date ?? 0).getTime()
|
|
32548
32554
|
);
|
|
32549
32555
|
}, [safeData]);
|
|
32550
32556
|
const points = React105.useMemo(() => {
|
|
@@ -33295,12 +33301,12 @@ var init_MapView = __esm({
|
|
|
33295
33301
|
shadowSize: [41, 41]
|
|
33296
33302
|
});
|
|
33297
33303
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
33298
|
-
const { useEffect: useEffect71, useRef:
|
|
33304
|
+
const { useEffect: useEffect71, useRef: useRef68, useCallback: useCallback104, useState: useState105 } = React105__namespace.default;
|
|
33299
33305
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
33300
33306
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
33301
33307
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
33302
33308
|
const map = useMap();
|
|
33303
|
-
const prevRef =
|
|
33309
|
+
const prevRef = useRef68({ centerLat, centerLng, zoom });
|
|
33304
33310
|
useEffect71(() => {
|
|
33305
33311
|
const prev = prevRef.current;
|
|
33306
33312
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
@@ -46291,7 +46297,7 @@ function getAllEvents(traits2) {
|
|
|
46291
46297
|
function EventDispatcherTab({ traits: traits2, schema }) {
|
|
46292
46298
|
const eventBus = useEventBus();
|
|
46293
46299
|
const { t } = hooks.useTranslate();
|
|
46294
|
-
const [
|
|
46300
|
+
const [log12, setLog] = React105__namespace.useState([]);
|
|
46295
46301
|
const prevStatesRef = React105__namespace.useRef(/* @__PURE__ */ new Map());
|
|
46296
46302
|
React105__namespace.useEffect(() => {
|
|
46297
46303
|
for (const trait of traits2) {
|
|
@@ -46355,9 +46361,9 @@ function EventDispatcherTab({ traits: traits2, schema }) {
|
|
|
46355
46361
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.otherEvents") }),
|
|
46356
46362
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-wrap gap-1", children: unavailableEvents.map((event) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: "default", size: "sm", className: "opacity-50", children: event }, event)) })
|
|
46357
46363
|
] }),
|
|
46358
|
-
|
|
46364
|
+
log12.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
46359
46365
|
/* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "small", weight: "medium", className: "text-gray-500 mb-1", children: t("debug.recentTransitions") }),
|
|
46360
|
-
/* @__PURE__ */ jsxRuntime.jsx(Stack, { gap: "xs", children:
|
|
46366
|
+
/* @__PURE__ */ jsxRuntime.jsx(Stack, { gap: "xs", children: log12.map((entry, i) => /* @__PURE__ */ jsxRuntime.jsxs(Typography, { variant: "small", className: "font-mono text-xs", children: [
|
|
46361
46367
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-purple-400", children: entry.traitName }),
|
|
46362
46368
|
" ",
|
|
46363
46369
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-gray-500", children: entry.from }),
|
|
@@ -53642,7 +53648,67 @@ function convertFnFormLambdasInProps(props) {
|
|
|
53642
53648
|
|
|
53643
53649
|
// hooks/index.ts
|
|
53644
53650
|
init_useEventBus();
|
|
53645
|
-
var log7 = logger.createLogger("almadar:ui:
|
|
53651
|
+
var log7 = logger.createLogger("almadar:ui:shared-entity-store");
|
|
53652
|
+
var EMPTY_ENTITY_STATE = {};
|
|
53653
|
+
function createSharedEntityStore() {
|
|
53654
|
+
const states = /* @__PURE__ */ new Map();
|
|
53655
|
+
const subscribers2 = /* @__PURE__ */ new Map();
|
|
53656
|
+
const getSnapshot2 = (entityId) => states.get(entityId) ?? EMPTY_ENTITY_STATE;
|
|
53657
|
+
const subscribe = (entityId, callback) => {
|
|
53658
|
+
let set = subscribers2.get(entityId);
|
|
53659
|
+
if (!set) {
|
|
53660
|
+
set = /* @__PURE__ */ new Set();
|
|
53661
|
+
subscribers2.set(entityId, set);
|
|
53662
|
+
}
|
|
53663
|
+
set.add(callback);
|
|
53664
|
+
return () => {
|
|
53665
|
+
const current = subscribers2.get(entityId);
|
|
53666
|
+
if (!current) return;
|
|
53667
|
+
current.delete(callback);
|
|
53668
|
+
if (current.size === 0) {
|
|
53669
|
+
subscribers2.delete(entityId);
|
|
53670
|
+
}
|
|
53671
|
+
};
|
|
53672
|
+
};
|
|
53673
|
+
const commit = (entityId, nextState) => {
|
|
53674
|
+
states.set(entityId, nextState);
|
|
53675
|
+
const set = subscribers2.get(entityId);
|
|
53676
|
+
if (!set) return;
|
|
53677
|
+
set.forEach((callback) => {
|
|
53678
|
+
try {
|
|
53679
|
+
callback();
|
|
53680
|
+
} catch (error) {
|
|
53681
|
+
log7.error("Shared entity subscriber error", {
|
|
53682
|
+
entityId,
|
|
53683
|
+
error: error instanceof Error ? error : String(error)
|
|
53684
|
+
});
|
|
53685
|
+
}
|
|
53686
|
+
});
|
|
53687
|
+
};
|
|
53688
|
+
const seed = (entityId, initialState) => {
|
|
53689
|
+
if (!states.has(entityId)) {
|
|
53690
|
+
states.set(entityId, initialState);
|
|
53691
|
+
}
|
|
53692
|
+
};
|
|
53693
|
+
return { getSnapshot: getSnapshot2, subscribe, commit, seed };
|
|
53694
|
+
}
|
|
53695
|
+
function useSharedEntityStore() {
|
|
53696
|
+
const storeRef = React105.useRef(null);
|
|
53697
|
+
if (storeRef.current === null) {
|
|
53698
|
+
storeRef.current = createSharedEntityStore();
|
|
53699
|
+
}
|
|
53700
|
+
return storeRef.current;
|
|
53701
|
+
}
|
|
53702
|
+
function runTickFrame(entityId, orderedWriters, store) {
|
|
53703
|
+
let scratch = store.getSnapshot(entityId);
|
|
53704
|
+
for (const writer of orderedWriters) {
|
|
53705
|
+
const writes = writer(scratch);
|
|
53706
|
+
scratch = core.mergeEntityFrame(scratch, writes);
|
|
53707
|
+
}
|
|
53708
|
+
store.commit(entityId, scratch);
|
|
53709
|
+
return scratch;
|
|
53710
|
+
}
|
|
53711
|
+
var log8 = logger.createLogger("almadar:ui:effects:client-handlers");
|
|
53646
53712
|
function createClientEffectHandlers(options) {
|
|
53647
53713
|
const { eventBus, slotSetter, navigate, notify, callService, liveEntity } = options;
|
|
53648
53714
|
return {
|
|
@@ -53651,12 +53717,12 @@ function createClientEffectHandlers(options) {
|
|
|
53651
53717
|
eventBus.emit(prefixedEvent, payload);
|
|
53652
53718
|
},
|
|
53653
53719
|
persist: async () => {
|
|
53654
|
-
|
|
53720
|
+
log8.warn("persist is server-side only, ignored on client");
|
|
53655
53721
|
},
|
|
53656
53722
|
// @almadar/runtime EffectHandlers.set types value:unknown — should be FieldValue (upstream fix queued)
|
|
53657
53723
|
set: ((_entityId, field, value) => {
|
|
53658
53724
|
if (!liveEntity) {
|
|
53659
|
-
|
|
53725
|
+
log8.warn("set is server-side only, ignored on client (no live entity)");
|
|
53660
53726
|
return;
|
|
53661
53727
|
}
|
|
53662
53728
|
liveEntity[field] = value;
|
|
@@ -53688,10 +53754,10 @@ function createClientEffectHandlers(options) {
|
|
|
53688
53754
|
slotSetter.addPattern(slot, pattern, props);
|
|
53689
53755
|
},
|
|
53690
53756
|
navigate: navigate ?? ((path) => {
|
|
53691
|
-
|
|
53757
|
+
log8.warn("No navigate handler, ignoring", { path });
|
|
53692
53758
|
}),
|
|
53693
53759
|
notify: notify ?? ((msg, type) => {
|
|
53694
|
-
|
|
53760
|
+
log8.debug("notify", { type, message: msg });
|
|
53695
53761
|
})
|
|
53696
53762
|
};
|
|
53697
53763
|
}
|
|
@@ -53736,11 +53802,101 @@ function toTraitDefinition(binding) {
|
|
|
53736
53802
|
function normalizeEventKey(eventKey) {
|
|
53737
53803
|
return eventKey.startsWith("UI:") ? eventKey.slice(3) : eventKey;
|
|
53738
53804
|
}
|
|
53805
|
+
var SHARED_ENTITY_WRITE_OPS = /* @__PURE__ */ new Set(["set"]);
|
|
53806
|
+
var SHARED_ENTITY_RENDER_OPS = /* @__PURE__ */ new Set(["render-ui", "render"]);
|
|
53807
|
+
function collectAllTraitEffects(trait) {
|
|
53808
|
+
return [
|
|
53809
|
+
...trait.ticks.flatMap((t) => t.effects),
|
|
53810
|
+
...trait.transitions.flatMap((t) => t.effects)
|
|
53811
|
+
];
|
|
53812
|
+
}
|
|
53813
|
+
function effectsCallOp(effects, ops) {
|
|
53814
|
+
for (const effect of effects) {
|
|
53815
|
+
let found = false;
|
|
53816
|
+
core.walkSExpr(effect, (node) => {
|
|
53817
|
+
if (!found && Array.isArray(node) && typeof node[0] === "string" && ops.has(node[0])) {
|
|
53818
|
+
found = true;
|
|
53819
|
+
}
|
|
53820
|
+
});
|
|
53821
|
+
if (found) return true;
|
|
53822
|
+
}
|
|
53823
|
+
return false;
|
|
53824
|
+
}
|
|
53825
|
+
function createSharedEntityWriter(binding, tick, traitStatesRef, emit) {
|
|
53826
|
+
return (scratch) => {
|
|
53827
|
+
const traitName = binding.trait.name;
|
|
53828
|
+
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
53829
|
+
if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return [];
|
|
53830
|
+
const scratchEntity = { ...scratch };
|
|
53831
|
+
const writes = [];
|
|
53832
|
+
const ctx = evaluator.createMinimalContext(scratchEntity, {}, currentState);
|
|
53833
|
+
const declaredDefaults = runtime.collectDeclaredConfigDefaults(binding.trait);
|
|
53834
|
+
const callSiteConfig = binding.config;
|
|
53835
|
+
if (declaredDefaults || callSiteConfig) {
|
|
53836
|
+
ctx.config = { ...declaredDefaults ?? {}, ...callSiteConfig ?? {} };
|
|
53837
|
+
}
|
|
53838
|
+
ctx.mutateEntity = (changes) => {
|
|
53839
|
+
for (const [field, value] of Object.entries(changes)) {
|
|
53840
|
+
const fieldValue = value;
|
|
53841
|
+
scratchEntity[field] = fieldValue;
|
|
53842
|
+
writes.push({ field, value: fieldValue });
|
|
53843
|
+
}
|
|
53844
|
+
};
|
|
53845
|
+
ctx.emit = (event, payload) => {
|
|
53846
|
+
emit(event, payload);
|
|
53847
|
+
};
|
|
53848
|
+
if (tick.guard !== void 0 && !evaluator.evaluateGuard(tick.guard, ctx)) {
|
|
53849
|
+
tickLog.debug("guard-blocked", { traitName, tick: tick.name, state: currentState });
|
|
53850
|
+
return [];
|
|
53851
|
+
}
|
|
53852
|
+
evaluator.executeEffects(tick.effects, ctx);
|
|
53853
|
+
return writes;
|
|
53854
|
+
};
|
|
53855
|
+
}
|
|
53739
53856
|
function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
53740
53857
|
const eventBus = useEventBus();
|
|
53741
53858
|
const { entities } = providers.useEntitySchema();
|
|
53742
53859
|
const traitConfigsByName = options?.traitConfigsByName;
|
|
53743
53860
|
const orbitalsByTrait = options?.orbitalsByTrait;
|
|
53861
|
+
const sharedEntityStore = useSharedEntityStore();
|
|
53862
|
+
const sharedGroups = React105.useMemo(() => {
|
|
53863
|
+
const groups = /* @__PURE__ */ new Map();
|
|
53864
|
+
for (const binding of traitBindings) {
|
|
53865
|
+
const linkedEntityName = binding.linkedEntity ?? binding.trait.linkedEntity;
|
|
53866
|
+
if (!linkedEntityName) continue;
|
|
53867
|
+
const entityDef = entities.get(linkedEntityName);
|
|
53868
|
+
if (!entityDef?.shared) continue;
|
|
53869
|
+
const orbitalName = orbitalsByTrait?.[binding.trait.name] ?? "";
|
|
53870
|
+
const storeKey = `${orbitalName}::${linkedEntityName}`;
|
|
53871
|
+
let group = groups.get(storeKey);
|
|
53872
|
+
if (!group) {
|
|
53873
|
+
let defaults;
|
|
53874
|
+
for (const field of entityDef.fields) {
|
|
53875
|
+
if (field.default !== void 0) {
|
|
53876
|
+
(defaults ?? (defaults = {}))[field.name] = field.default;
|
|
53877
|
+
}
|
|
53878
|
+
}
|
|
53879
|
+
group = { storeKey, entityName: linkedEntityName, writerBindings: [], renderBindings: [], defaults };
|
|
53880
|
+
groups.set(storeKey, group);
|
|
53881
|
+
}
|
|
53882
|
+
const allEffects = collectAllTraitEffects(binding.trait);
|
|
53883
|
+
if (effectsCallOp(allEffects, SHARED_ENTITY_WRITE_OPS)) group.writerBindings.push(binding);
|
|
53884
|
+
if (effectsCallOp(allEffects, SHARED_ENTITY_RENDER_OPS)) group.renderBindings.push(binding);
|
|
53885
|
+
}
|
|
53886
|
+
return groups;
|
|
53887
|
+
}, [traitBindings, entities, orbitalsByTrait]);
|
|
53888
|
+
for (const group of sharedGroups.values()) {
|
|
53889
|
+
if (group.defaults) sharedEntityStore.seed(group.storeKey, group.defaults);
|
|
53890
|
+
}
|
|
53891
|
+
const sharedKeyByTraitNameRef = React105.useRef(/* @__PURE__ */ new Map());
|
|
53892
|
+
React105.useEffect(() => {
|
|
53893
|
+
const map = /* @__PURE__ */ new Map();
|
|
53894
|
+
for (const group of sharedGroups.values()) {
|
|
53895
|
+
for (const binding of group.writerBindings) map.set(binding.trait.name, group.storeKey);
|
|
53896
|
+
for (const binding of group.renderBindings) map.set(binding.trait.name, group.storeKey);
|
|
53897
|
+
}
|
|
53898
|
+
sharedKeyByTraitNameRef.current = map;
|
|
53899
|
+
}, [sharedGroups]);
|
|
53744
53900
|
const manager = React105.useMemo(() => {
|
|
53745
53901
|
const traitDefs = traitBindings.map(toTraitDefinition);
|
|
53746
53902
|
const m = new runtime.StateMachineManager(traitDefs);
|
|
@@ -53923,14 +54079,21 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
53923
54079
|
};
|
|
53924
54080
|
}, [traitBindings]);
|
|
53925
54081
|
const executeTransitionEffects = React105.useCallback(async (params) => {
|
|
53926
|
-
const { binding, previousState, newState, payload, flushEvent, syncOnly, log:
|
|
54082
|
+
const { binding, previousState, newState, payload, flushEvent, syncOnly, log: log12 } = params;
|
|
53927
54083
|
const traitName = binding.trait.name;
|
|
53928
54084
|
const linkedEntity = binding.linkedEntity || "";
|
|
53929
54085
|
const entityId = payload?.entityId;
|
|
53930
|
-
|
|
53931
|
-
|
|
53932
|
-
|
|
53933
|
-
|
|
54086
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(traitName);
|
|
54087
|
+
let liveEntity;
|
|
54088
|
+
if (sharedKey !== void 0) {
|
|
54089
|
+
liveEntity = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
54090
|
+
} else {
|
|
54091
|
+
let existing = traitFieldStatesRef.current.get(traitName);
|
|
54092
|
+
if (!existing) {
|
|
54093
|
+
existing = {};
|
|
54094
|
+
traitFieldStatesRef.current.set(traitName, existing);
|
|
54095
|
+
}
|
|
54096
|
+
liveEntity = existing;
|
|
53934
54097
|
}
|
|
53935
54098
|
const effects = syncOnly ? params.effects.filter(
|
|
53936
54099
|
(e) => Array.isArray(e) && SYNC_TICK_OPERATORS.has(String(e[0]))
|
|
@@ -54012,7 +54175,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
54012
54175
|
...handlers,
|
|
54013
54176
|
set: async (targetId, field, value) => {
|
|
54014
54177
|
if (baseSet) await baseSet(targetId, field, value);
|
|
54015
|
-
|
|
54178
|
+
log12.debug("set:write", {
|
|
54016
54179
|
traitName,
|
|
54017
54180
|
field,
|
|
54018
54181
|
value: JSON.stringify(value),
|
|
@@ -54052,17 +54215,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
54052
54215
|
const executor = new runtime.EffectExecutor({ handlers: trackingHandlers, bindings: bindingCtx, context: effectContext });
|
|
54053
54216
|
try {
|
|
54054
54217
|
await executor.executeAll(effects);
|
|
54055
|
-
|
|
54218
|
+
if (sharedKey !== void 0) {
|
|
54219
|
+
sharedEntityStore.commit(sharedKey, liveEntity);
|
|
54220
|
+
}
|
|
54221
|
+
log12.debug("effects:executed", () => ({
|
|
54056
54222
|
traitName,
|
|
54057
54223
|
transition: `${previousState}->${newState}`,
|
|
54058
54224
|
event: flushEvent,
|
|
54059
54225
|
effectCount: effects.length,
|
|
54060
54226
|
emitted: emittedDuringExec.join(","),
|
|
54061
|
-
entityAfter: JSON.stringify(
|
|
54227
|
+
entityAfter: JSON.stringify(liveEntity ?? {}),
|
|
54062
54228
|
slotsTouched: Array.from(pendingSlots.keys()).join(",")
|
|
54063
54229
|
}));
|
|
54064
54230
|
for (const [slot, patterns] of pendingSlots) {
|
|
54065
|
-
|
|
54231
|
+
log12.debug("flush:slot", {
|
|
54066
54232
|
traitName,
|
|
54067
54233
|
slot,
|
|
54068
54234
|
patternCount: patterns.length,
|
|
@@ -54077,7 +54243,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
54077
54243
|
});
|
|
54078
54244
|
}
|
|
54079
54245
|
} catch (error) {
|
|
54080
|
-
|
|
54246
|
+
log12.error("effects:error", {
|
|
54081
54247
|
traitName,
|
|
54082
54248
|
transition: `${previousState}->${newState}`,
|
|
54083
54249
|
event: flushEvent,
|
|
@@ -54086,14 +54252,16 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
54086
54252
|
});
|
|
54087
54253
|
}
|
|
54088
54254
|
return emittedDuringExec;
|
|
54089
|
-
}, [eventBus, flushSlot]);
|
|
54255
|
+
}, [eventBus, flushSlot, sharedEntityStore]);
|
|
54090
54256
|
const runTickEffects = React105.useCallback((tick, binding) => {
|
|
54091
54257
|
const traitName = binding.trait.name;
|
|
54092
54258
|
const currentState = traitStatesRef.current.get(traitName)?.currentState ?? "";
|
|
54093
54259
|
if (tick.appliesTo.length > 0 && !tick.appliesTo.includes(currentState)) return;
|
|
54094
54260
|
if (tick.guard !== void 0) {
|
|
54261
|
+
const sharedKey = sharedKeyByTraitNameRef.current.get(traitName);
|
|
54262
|
+
const entity = sharedKey !== void 0 ? sharedEntityStore.getSnapshot(sharedKey) : traitFieldStatesRef.current.get(traitName) ?? {};
|
|
54095
54263
|
const guardCtx = {
|
|
54096
|
-
entity
|
|
54264
|
+
entity,
|
|
54097
54265
|
payload: {},
|
|
54098
54266
|
state: currentState
|
|
54099
54267
|
};
|
|
@@ -54118,10 +54286,46 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
54118
54286
|
syncOnly: true,
|
|
54119
54287
|
log: tickLog
|
|
54120
54288
|
});
|
|
54121
|
-
}, [executeTransitionEffects]);
|
|
54289
|
+
}, [executeTransitionEffects, sharedEntityStore]);
|
|
54290
|
+
const emitFromSharedWriter = React105.useCallback((event, payload) => {
|
|
54291
|
+
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
54292
|
+
eventBus.emit(prefixedEvent, payload);
|
|
54293
|
+
}, [eventBus]);
|
|
54122
54294
|
React105.useEffect(() => {
|
|
54123
54295
|
const scheduler = runtime.createTickScheduler();
|
|
54296
|
+
const writerTraitNames = /* @__PURE__ */ new Set();
|
|
54297
|
+
for (const group of sharedGroups.values()) {
|
|
54298
|
+
const ticksByInterval = /* @__PURE__ */ new Map();
|
|
54299
|
+
for (const binding of group.writerBindings) {
|
|
54300
|
+
writerTraitNames.add(binding.trait.name);
|
|
54301
|
+
for (const tick of binding.trait.ticks ?? []) {
|
|
54302
|
+
const intervalKey = String(tick.interval);
|
|
54303
|
+
const entries = ticksByInterval.get(intervalKey) ?? [];
|
|
54304
|
+
entries.push({ binding, tick });
|
|
54305
|
+
ticksByInterval.set(intervalKey, entries);
|
|
54306
|
+
}
|
|
54307
|
+
}
|
|
54308
|
+
for (const entries of ticksByInterval.values()) {
|
|
54309
|
+
const interval = entries[0].tick.interval;
|
|
54310
|
+
const onDue = () => {
|
|
54311
|
+
const writers = entries.map(
|
|
54312
|
+
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
54313
|
+
);
|
|
54314
|
+
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
54315
|
+
};
|
|
54316
|
+
if (interval === "frame") {
|
|
54317
|
+
scheduler.add(0, onDue);
|
|
54318
|
+
} else if (typeof interval === "number") {
|
|
54319
|
+
scheduler.add(interval, onDue);
|
|
54320
|
+
} else if (runtime.isValidCronExpression(interval)) {
|
|
54321
|
+
scheduler.addCron(interval, onDue);
|
|
54322
|
+
} else {
|
|
54323
|
+
scheduler.add(runtime.parseDurationString(interval), onDue);
|
|
54324
|
+
}
|
|
54325
|
+
}
|
|
54326
|
+
}
|
|
54124
54327
|
for (const binding of traitBindings) {
|
|
54328
|
+
if (writerTraitNames.has(binding.trait.name)) continue;
|
|
54125
54329
|
for (const tick of binding.trait.ticks ?? []) {
|
|
54126
54330
|
if (tick.interval === "frame") {
|
|
54127
54331
|
scheduler.add(0, () => runTickEffects(tick, binding));
|
|
@@ -54135,7 +54339,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
54135
54339
|
}
|
|
54136
54340
|
}
|
|
54137
54341
|
return () => scheduler.stopAll();
|
|
54138
|
-
}, [traitBindings, runTickEffects]);
|
|
54342
|
+
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
54139
54343
|
const processEventQueued = React105.useCallback(async (eventKey, payload) => {
|
|
54140
54344
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
54141
54345
|
const bindings = traitBindingsRef.current;
|
|
@@ -54479,7 +54683,7 @@ function buildOrbitalsByTrait(schema, resolvedPages = []) {
|
|
|
54479
54683
|
// runtime/OrbPreview.tsx
|
|
54480
54684
|
init_verificationRegistry();
|
|
54481
54685
|
var PERF_NAMESPACE = "almadar:perf:canvas";
|
|
54482
|
-
var
|
|
54686
|
+
var log9 = logger.createLogger(PERF_NAMESPACE);
|
|
54483
54687
|
var RING_SIZE = 50;
|
|
54484
54688
|
var ring = [];
|
|
54485
54689
|
var writeIdx = 0;
|
|
@@ -54530,7 +54734,7 @@ function perfEnd(name, startToken, detail) {
|
|
|
54530
54734
|
}
|
|
54531
54735
|
}
|
|
54532
54736
|
push({ name, durationMs, ts: endTs, detail });
|
|
54533
|
-
|
|
54737
|
+
log9.debug(name, () => ({ durationMs, ...detail ?? {} }));
|
|
54534
54738
|
}
|
|
54535
54739
|
var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
54536
54740
|
if (!isEnabled()) return;
|
|
@@ -54540,7 +54744,7 @@ var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, com
|
|
|
54540
54744
|
ts: commitTime,
|
|
54541
54745
|
detail: { baseDuration }
|
|
54542
54746
|
});
|
|
54543
|
-
|
|
54747
|
+
log9.debug(`profiler:${id}:${phase}`, () => ({ actualDuration, baseDuration }));
|
|
54544
54748
|
};
|
|
54545
54749
|
|
|
54546
54750
|
// lib/prepareSchemaForPreview.ts
|
|
@@ -55182,7 +55386,7 @@ init_useEventBus();
|
|
|
55182
55386
|
// components/avl/hooks/useCanvasDnd.tsx
|
|
55183
55387
|
init_useEventBus();
|
|
55184
55388
|
init_useAlmadarDndCollision();
|
|
55185
|
-
var
|
|
55389
|
+
var log10 = logger.createLogger("almadar:ui:canvas-dnd");
|
|
55186
55390
|
function useCanvasDraggable({
|
|
55187
55391
|
id,
|
|
55188
55392
|
payload,
|
|
@@ -55221,7 +55425,7 @@ function defaultEmit(eventBus, drop) {
|
|
|
55221
55425
|
if (payload.kind === "pattern") {
|
|
55222
55426
|
const patternType = payload.data["type"];
|
|
55223
55427
|
if (typeof patternType !== "string") {
|
|
55224
|
-
|
|
55428
|
+
log10.warn("default-emit:pattern:missing-type");
|
|
55225
55429
|
return;
|
|
55226
55430
|
}
|
|
55227
55431
|
const out = { patternType, containerNode: target.containerNode };
|
|
@@ -55230,23 +55434,23 @@ function defaultEmit(eventBus, drop) {
|
|
|
55230
55434
|
out.index = resolved.index;
|
|
55231
55435
|
}
|
|
55232
55436
|
eventBus.emit("UI:PATTERN_DROP", out);
|
|
55233
|
-
|
|
55437
|
+
log10.info("default-emit:pattern", { patternType, level: target.level });
|
|
55234
55438
|
return;
|
|
55235
55439
|
}
|
|
55236
55440
|
if (payload.kind === "behavior") {
|
|
55237
55441
|
const behaviorName = payload.data["name"];
|
|
55238
55442
|
if (typeof behaviorName !== "string") {
|
|
55239
|
-
|
|
55443
|
+
log10.warn("default-emit:behavior:missing-name");
|
|
55240
55444
|
return;
|
|
55241
55445
|
}
|
|
55242
55446
|
eventBus.emit("UI:BEHAVIOR_DROP", {
|
|
55243
55447
|
behaviorName,
|
|
55244
55448
|
containerNode: target.containerNode
|
|
55245
55449
|
});
|
|
55246
|
-
|
|
55450
|
+
log10.info("default-emit:behavior", { behaviorName, level: target.level });
|
|
55247
55451
|
return;
|
|
55248
55452
|
}
|
|
55249
|
-
|
|
55453
|
+
log10.debug("default-emit:unhandled-kind", { kind: payload.kind });
|
|
55250
55454
|
}
|
|
55251
55455
|
function CanvasDndProvider({
|
|
55252
55456
|
children,
|
|
@@ -55262,9 +55466,9 @@ function CanvasDndProvider({
|
|
|
55262
55466
|
if (payload) {
|
|
55263
55467
|
setActivePayload(payload);
|
|
55264
55468
|
eventBus.emit("UI:DRAG_START", { kind: payload.kind, data: payload.data });
|
|
55265
|
-
|
|
55469
|
+
log10.info("dragStart", { id: e.active.id, kind: payload.kind });
|
|
55266
55470
|
} else {
|
|
55267
|
-
|
|
55471
|
+
log10.warn("dragStart:missing-payload", { id: e.active.id });
|
|
55268
55472
|
}
|
|
55269
55473
|
}, [eventBus]);
|
|
55270
55474
|
const handleDragEnd = React105__namespace.default.useCallback((e) => {
|
|
@@ -55274,7 +55478,7 @@ function CanvasDndProvider({
|
|
|
55274
55478
|
const overData = e.over?.data.current;
|
|
55275
55479
|
const target = overData?.target;
|
|
55276
55480
|
const accepts = overData?.accepts;
|
|
55277
|
-
|
|
55481
|
+
log10.info("dragEnd", {
|
|
55278
55482
|
activeId: e.active.id,
|
|
55279
55483
|
overId: e.over?.id,
|
|
55280
55484
|
hasPayload: !!payload,
|
|
@@ -55286,7 +55490,7 @@ function CanvasDndProvider({
|
|
|
55286
55490
|
}
|
|
55287
55491
|
if (!payload || !target) return;
|
|
55288
55492
|
if (accepts && !accepts.includes(payload.kind)) {
|
|
55289
|
-
|
|
55493
|
+
log10.debug("dragEnd:rejected:kind", { kind: payload.kind, accepts: [...accepts] });
|
|
55290
55494
|
return;
|
|
55291
55495
|
}
|
|
55292
55496
|
const activator = e.activatorEvent;
|
|
@@ -55298,7 +55502,7 @@ function CanvasDndProvider({
|
|
|
55298
55502
|
}, [eventBus, onDrop]);
|
|
55299
55503
|
const handleDragCancel = React105__namespace.default.useCallback(() => {
|
|
55300
55504
|
setActivePayload(null);
|
|
55301
|
-
|
|
55505
|
+
log10.info("dragCancel");
|
|
55302
55506
|
}, []);
|
|
55303
55507
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
55304
55508
|
core$1.DndContext,
|
|
@@ -57131,7 +57335,7 @@ init_AvlTransitionLane();
|
|
|
57131
57335
|
init_AvlSwimLane();
|
|
57132
57336
|
init_avl_atom_types();
|
|
57133
57337
|
init_avl_elk_layout();
|
|
57134
|
-
var
|
|
57338
|
+
var log11 = logger.createLogger("almadar:ui:avl:trait-scene");
|
|
57135
57339
|
var SWIM_GUTTER2 = 120;
|
|
57136
57340
|
var CENTER_W2 = 360;
|
|
57137
57341
|
var AvlTraitScene = ({
|
|
@@ -57144,7 +57348,7 @@ var AvlTraitScene = ({
|
|
|
57144
57348
|
const dataKey = React105.useMemo(() => JSON.stringify(data), [data]);
|
|
57145
57349
|
React105.useEffect(() => {
|
|
57146
57350
|
computeTraitLayout(data).then(setLayout).catch((error) => {
|
|
57147
|
-
|
|
57351
|
+
log11.error("computeTraitLayout failed", { error: error instanceof Error ? error : String(error) });
|
|
57148
57352
|
});
|
|
57149
57353
|
}, [dataKey]);
|
|
57150
57354
|
if (!layout) {
|
package/dist/avl/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* node_modules/katex/dist/katex.min.css */
|
|
1
|
+
/* node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css */
|
|
2
2
|
@font-face {
|
|
3
3
|
font-display: block;
|
|
4
4
|
font-family: KaTeX_AMS;
|
|
@@ -214,11 +214,11 @@
|
|
|
214
214
|
border-color: currentColor;
|
|
215
215
|
}
|
|
216
216
|
.katex .katex-version:after {
|
|
217
|
-
content: "0.16.
|
|
217
|
+
content: "0.16.47";
|
|
218
218
|
}
|
|
219
219
|
.katex .katex-mathml {
|
|
220
|
-
clip: rect(1px, 1px, 1px, 1px);
|
|
221
220
|
border: 0;
|
|
221
|
+
clip-path: inset(50%);
|
|
222
222
|
height: 1px;
|
|
223
223
|
overflow: hidden;
|
|
224
224
|
padding: 0;
|