@almadar/ui 5.70.0 → 5.72.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 +2198 -2218
- package/dist/avl/index.d.cts +93 -56
- package/dist/avl/index.js +931 -951
- package/dist/components/avl/molecules/AvlEventWireEdge.d.ts +2 -1
- package/dist/components/avl/molecules/AvlTransitionEdge.d.ts +2 -1
- package/dist/components/avl/molecules/avl-behavior-compose-converter.d.ts +7 -5
- package/dist/components/avl/molecules/avl-behavior-compose-types.d.ts +41 -21
- package/dist/components/avl/molecules/avl-canvas-types.d.ts +10 -7
- package/dist/components/avl/molecules/avl-preview-converter.d.ts +5 -5
- package/dist/components/avl/molecules/avl-preview-types.d.ts +15 -4
- package/dist/components/avl/organisms/FlowCanvas.d.ts +2 -2
- package/dist/components/avl/organisms/avl-schema-parser.d.ts +18 -16
- package/dist/components/core/atoms/Button.d.ts +2 -0
- package/dist/components/core/atoms/ConditionalWrapper.d.ts +5 -4
- package/dist/components/core/molecules/Carousel.d.ts +2 -2
- package/dist/components/core/molecules/OrbitalVisualization.d.ts +4 -3
- package/dist/components/core/molecules/PageHeader.d.ts +3 -3
- package/dist/components/core/molecules/RepeatableFormSection.d.ts +4 -3
- package/dist/components/core/molecules/ViolationAlert.d.ts +2 -0
- package/dist/components/core/molecules/WizardContainer.d.ts +23 -22
- package/dist/components/core/organisms/CardGrid.d.ts +2 -2
- package/dist/components/core/organisms/CustomPattern.d.ts +3 -4
- package/dist/components/core/organisms/DataTable.d.ts +2 -2
- package/dist/components/core/organisms/DetailPanel.d.ts +1 -1
- package/dist/components/core/organisms/Form.d.ts +11 -11
- package/dist/components/core/organisms/List.d.ts +3 -5
- package/dist/components/core/organisms/StatCard.d.ts +2 -2
- package/dist/components/core/organisms/book/types.d.ts +1 -1
- package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +2 -1
- package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
- package/dist/components/core/organisms/layout/DashboardGrid.d.ts +0 -2
- package/dist/components/core/organisms/types.d.ts +3 -2
- package/dist/components/game/atoms/ScoreDisplay.d.ts +3 -3
- package/dist/components/game/atoms/Sprite.d.ts +6 -1
- package/dist/components/game/atoms/XPBar.d.ts +1 -1
- package/dist/components/game/molecules/GameCanvas3D.d.ts +0 -2
- package/dist/components/game/molecules/IsometricCanvas.d.ts +4 -2
- package/dist/components/game/molecules/PlatformerCanvas.d.ts +4 -1
- package/dist/components/game/molecules/StatBadge.d.ts +3 -1
- package/dist/components/game/molecules/three/hooks/useSceneGraph.d.ts +2 -1
- package/dist/components/game/molecules/three/index.cjs +41 -105
- package/dist/components/game/molecules/three/index.js +41 -105
- package/dist/components/game/molecules/useUnitSpriteAtlas.d.ts +3 -2
- package/dist/components/game/organisms/PinballBoard.d.ts +4 -4
- package/dist/components/game/organisms/boardEntity.d.ts +6 -6
- package/dist/components/game/organisms/puzzles/debugger/DebuggerBoard.d.ts +16 -2
- package/dist/components/game/organisms/puzzles/event-handler/puzzleObject.d.ts +21 -10
- package/dist/components/game/organisms/puzzles/state-architect/StateJsonView.d.ts +2 -1
- package/dist/components/game/organisms/types/isometric.d.ts +16 -0
- package/dist/components/index.cjs +2228 -2251
- package/dist/components/index.js +1116 -1139
- package/dist/docs/index.cjs +107 -104
- package/dist/docs/index.d.cts +2 -0
- package/dist/docs/index.js +38 -35
- package/dist/lib/getNestedValue.d.ts +2 -13
- package/dist/marketing/index.cjs +97 -98
- package/dist/marketing/index.d.cts +2 -0
- package/dist/marketing/index.js +54 -55
- package/dist/providers/index.cjs +1908 -1951
- package/dist/providers/index.js +808 -851
- package/dist/runtime/index.cjs +1966 -2009
- package/dist/runtime/index.js +814 -857
- package/package.json +1 -1
|
@@ -2293,13 +2293,6 @@ function preloadFeatures(urls) {
|
|
|
2293
2293
|
}
|
|
2294
2294
|
|
|
2295
2295
|
// components/game/organisms/utils/spriteAnimation.ts
|
|
2296
|
-
function inferDirection(dx, dy) {
|
|
2297
|
-
if (dx === 0 && dy === 0) return "se";
|
|
2298
|
-
if (dx >= 0 && dy >= 0) return "se";
|
|
2299
|
-
if (dx <= 0 && dy >= 0) return "sw";
|
|
2300
|
-
if (dx >= 0 && dy <= 0) return "ne";
|
|
2301
|
-
return "nw";
|
|
2302
|
-
}
|
|
2303
2296
|
function resolveSheetDirection(facing) {
|
|
2304
2297
|
switch (facing) {
|
|
2305
2298
|
case "se":
|
|
@@ -2320,22 +2313,8 @@ function frameRect(frame, row, columns, frameWidth, frameHeight) {
|
|
|
2320
2313
|
sh: frameHeight
|
|
2321
2314
|
};
|
|
2322
2315
|
}
|
|
2323
|
-
function getCurrentFrameFromDef(def, elapsed) {
|
|
2324
|
-
const frameDuration = 1e3 / def.frameRate;
|
|
2325
|
-
const totalDuration = def.frames * frameDuration;
|
|
2326
|
-
if (def.loop) {
|
|
2327
|
-
const frame2 = Math.floor(elapsed % totalDuration / frameDuration);
|
|
2328
|
-
return { frame: frame2, finished: false };
|
|
2329
|
-
}
|
|
2330
|
-
if (elapsed >= totalDuration) {
|
|
2331
|
-
return { frame: def.frames - 1, finished: true };
|
|
2332
|
-
}
|
|
2333
|
-
const frame = Math.floor(elapsed / frameDuration);
|
|
2334
|
-
return { frame, finished: false };
|
|
2335
|
-
}
|
|
2336
2316
|
|
|
2337
2317
|
// components/game/molecules/useUnitSpriteAtlas.ts
|
|
2338
|
-
var WALK_HOLD_MS = 600;
|
|
2339
2318
|
function unitAtlasUrl(unit) {
|
|
2340
2319
|
if (unit.spriteSheet) return unit.spriteSheet;
|
|
2341
2320
|
const sprite = unit.sprite;
|
|
@@ -2357,9 +2336,6 @@ function useUnitSpriteAtlas(units) {
|
|
|
2357
2336
|
const loadingRef = React11.useRef(/* @__PURE__ */ new Set());
|
|
2358
2337
|
const [pendingCount, setPendingCount] = React11.useState(0);
|
|
2359
2338
|
const [, forceTick] = React11.useState(0);
|
|
2360
|
-
const animStatesRef = React11.useRef(/* @__PURE__ */ new Map());
|
|
2361
|
-
const lastTickRef = React11.useRef(0);
|
|
2362
|
-
const rafRef = React11.useRef(0);
|
|
2363
2339
|
const atlasUrls = React11.useMemo(() => {
|
|
2364
2340
|
const set = /* @__PURE__ */ new Set();
|
|
2365
2341
|
for (const unit of units) {
|
|
@@ -2405,54 +2381,6 @@ function useUnitSpriteAtlas(units) {
|
|
|
2405
2381
|
}
|
|
2406
2382
|
return [...urls];
|
|
2407
2383
|
}, [units, pendingCount]);
|
|
2408
|
-
React11.useEffect(() => {
|
|
2409
|
-
const hasAtlasUnits = units.some((u) => unitAtlasUrl(u) !== null);
|
|
2410
|
-
if (!hasAtlasUnits) return;
|
|
2411
|
-
let running = true;
|
|
2412
|
-
const tick = (ts) => {
|
|
2413
|
-
if (!running) return;
|
|
2414
|
-
const last = lastTickRef.current || ts;
|
|
2415
|
-
const delta = ts - last;
|
|
2416
|
-
lastTickRef.current = ts;
|
|
2417
|
-
const states = animStatesRef.current;
|
|
2418
|
-
const currentIds = /* @__PURE__ */ new Set();
|
|
2419
|
-
for (const unit of units) {
|
|
2420
|
-
if (unitAtlasUrl(unit) === null) continue;
|
|
2421
|
-
currentIds.add(unit.id);
|
|
2422
|
-
let state = states.get(unit.id);
|
|
2423
|
-
if (!state) {
|
|
2424
|
-
state = { animation: "idle", direction: "se", elapsed: 0, walkHold: 0, prev: null };
|
|
2425
|
-
states.set(unit.id, state);
|
|
2426
|
-
}
|
|
2427
|
-
const posX = unit.position?.x ?? unit.x ?? 0;
|
|
2428
|
-
const posY = unit.position?.y ?? unit.y ?? 0;
|
|
2429
|
-
if (state.prev) {
|
|
2430
|
-
const dx = posX - state.prev.x;
|
|
2431
|
-
const dy = posY - state.prev.y;
|
|
2432
|
-
if (dx !== 0 || dy !== 0) {
|
|
2433
|
-
state.animation = "walk";
|
|
2434
|
-
state.direction = inferDirection(dx, dy);
|
|
2435
|
-
state.walkHold = WALK_HOLD_MS;
|
|
2436
|
-
} else if (state.animation === "walk") {
|
|
2437
|
-
state.walkHold -= delta;
|
|
2438
|
-
if (state.walkHold <= 0) state.animation = "idle";
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
state.prev = { x: posX, y: posY };
|
|
2442
|
-
state.elapsed += delta;
|
|
2443
|
-
}
|
|
2444
|
-
for (const id of states.keys()) {
|
|
2445
|
-
if (!currentIds.has(id)) states.delete(id);
|
|
2446
|
-
}
|
|
2447
|
-
rafRef.current = requestAnimationFrame(tick);
|
|
2448
|
-
};
|
|
2449
|
-
rafRef.current = requestAnimationFrame(tick);
|
|
2450
|
-
return () => {
|
|
2451
|
-
running = false;
|
|
2452
|
-
cancelAnimationFrame(rafRef.current);
|
|
2453
|
-
lastTickRef.current = 0;
|
|
2454
|
-
};
|
|
2455
|
-
}, [units]);
|
|
2456
2384
|
const resolveUnitFrame = React11.useCallback((unitId) => {
|
|
2457
2385
|
const unit = units.find((u) => u.id === unitId);
|
|
2458
2386
|
if (!unit) return null;
|
|
@@ -2460,18 +2388,14 @@ function useUnitSpriteAtlas(units) {
|
|
|
2460
2388
|
if (!atlasUrl) return null;
|
|
2461
2389
|
const atlas = atlasCacheRef.current.get(atlasUrl);
|
|
2462
2390
|
if (!atlas) return null;
|
|
2463
|
-
const
|
|
2464
|
-
const
|
|
2465
|
-
const direction = state?.direction ?? "se";
|
|
2466
|
-
const elapsed = state?.elapsed ?? 0;
|
|
2391
|
+
const animation = unit.animation ?? "idle";
|
|
2392
|
+
const frame = unit.frame ?? 0;
|
|
2467
2393
|
const def = atlas.animations[animation] ?? atlas.animations.idle;
|
|
2468
2394
|
if (!def) return null;
|
|
2469
|
-
const { sheetDir, flipX } = resolveSheetDirection(
|
|
2395
|
+
const { sheetDir, flipX } = resolveSheetDirection("se");
|
|
2470
2396
|
const rel = atlas.sheets[sheetDir] ?? atlas.sheets.se ?? atlas.sheets.sw;
|
|
2471
2397
|
if (!rel) return null;
|
|
2472
2398
|
const sheetUrl = resolveSheetUrl(atlasUrl, rel);
|
|
2473
|
-
const isIdle = animation === "idle";
|
|
2474
|
-
const frame = isIdle ? 0 : getCurrentFrameFromDef(def, elapsed).frame;
|
|
2475
2399
|
const rect = frameRect(frame, def.row, atlas.columns, atlas.frameWidth, atlas.frameHeight);
|
|
2476
2400
|
return {
|
|
2477
2401
|
sheetUrl,
|
|
@@ -2480,7 +2404,7 @@ function useUnitSpriteAtlas(units) {
|
|
|
2480
2404
|
sw: rect.sw,
|
|
2481
2405
|
sh: rect.sh,
|
|
2482
2406
|
flipX,
|
|
2483
|
-
applyBreathing:
|
|
2407
|
+
applyBreathing: animation === "idle"
|
|
2484
2408
|
};
|
|
2485
2409
|
}, [units]);
|
|
2486
2410
|
return { sheetUrls, resolveUnitFrame, pendingCount };
|
|
@@ -2576,7 +2500,6 @@ var GameCanvas3D = React11.forwardRef(
|
|
|
2576
2500
|
className,
|
|
2577
2501
|
isLoading: externalLoading,
|
|
2578
2502
|
error: externalError,
|
|
2579
|
-
entity,
|
|
2580
2503
|
preloadAssets = [],
|
|
2581
2504
|
tileClickEvent,
|
|
2582
2505
|
unitClickEvent,
|
|
@@ -3989,6 +3912,9 @@ var iconSizeStyles = {
|
|
|
3989
3912
|
md: "h-icon-default w-icon-default",
|
|
3990
3913
|
lg: "h-icon-default w-icon-default"
|
|
3991
3914
|
};
|
|
3915
|
+
function isIconLike(v) {
|
|
3916
|
+
return typeof v.render === "function";
|
|
3917
|
+
}
|
|
3992
3918
|
function resolveIconProp(value, sizeClass) {
|
|
3993
3919
|
if (!value) return null;
|
|
3994
3920
|
if (typeof value === "string") {
|
|
@@ -4001,7 +3927,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
4001
3927
|
if (React11__default.default.isValidElement(value)) {
|
|
4002
3928
|
return value;
|
|
4003
3929
|
}
|
|
4004
|
-
if (typeof value === "object" && value !== null &&
|
|
3930
|
+
if (typeof value === "object" && value !== null && isIconLike(value)) {
|
|
4005
3931
|
const IconComp = value;
|
|
4006
3932
|
return /* @__PURE__ */ jsxRuntime.jsx(IconComp, { className: sizeClass });
|
|
4007
3933
|
}
|
|
@@ -4023,6 +3949,7 @@ var Button = React11__default.default.forwardRef(
|
|
|
4023
3949
|
label,
|
|
4024
3950
|
children,
|
|
4025
3951
|
onClick,
|
|
3952
|
+
"data-testid": dataTestId,
|
|
4026
3953
|
...props
|
|
4027
3954
|
}, ref) => {
|
|
4028
3955
|
const eventBus = useEventBus();
|
|
@@ -4055,7 +3982,7 @@ var Button = React11__default.default.forwardRef(
|
|
|
4055
3982
|
),
|
|
4056
3983
|
onClick: handleClick,
|
|
4057
3984
|
...props,
|
|
4058
|
-
"data-testid":
|
|
3985
|
+
"data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
|
|
4059
3986
|
children: [
|
|
4060
3987
|
isLoading ? /* @__PURE__ */ jsxRuntime.jsx(LucideIcons.Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
4061
3988
|
children || label,
|
|
@@ -4152,9 +4079,8 @@ var Typography = ({
|
|
|
4152
4079
|
}) => {
|
|
4153
4080
|
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
4154
4081
|
const Component2 = as || defaultElements[variant];
|
|
4155
|
-
|
|
4156
|
-
|
|
4157
|
-
Comp,
|
|
4082
|
+
return React11__default.default.createElement(
|
|
4083
|
+
Component2,
|
|
4158
4084
|
{
|
|
4159
4085
|
id,
|
|
4160
4086
|
className: cn(
|
|
@@ -4167,9 +4093,9 @@ var Typography = ({
|
|
|
4167
4093
|
overflow && overflowStyles[overflow],
|
|
4168
4094
|
className
|
|
4169
4095
|
),
|
|
4170
|
-
style
|
|
4171
|
-
|
|
4172
|
-
|
|
4096
|
+
style
|
|
4097
|
+
},
|
|
4098
|
+
children ?? content
|
|
4173
4099
|
);
|
|
4174
4100
|
};
|
|
4175
4101
|
Typography.displayName = "Typography";
|
|
@@ -4226,9 +4152,8 @@ var Stack = ({
|
|
|
4226
4152
|
};
|
|
4227
4153
|
const isHorizontal = direction === "horizontal";
|
|
4228
4154
|
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
Comp,
|
|
4155
|
+
return React11__default.default.createElement(
|
|
4156
|
+
Component2,
|
|
4232
4157
|
{
|
|
4233
4158
|
className: cn(
|
|
4234
4159
|
"flex",
|
|
@@ -4244,9 +4169,9 @@ var Stack = ({
|
|
|
4244
4169
|
onClick: action || onClick ? handleClick : void 0,
|
|
4245
4170
|
onKeyDown,
|
|
4246
4171
|
role,
|
|
4247
|
-
tabIndex
|
|
4248
|
-
|
|
4249
|
-
|
|
4172
|
+
tabIndex
|
|
4173
|
+
},
|
|
4174
|
+
children
|
|
4250
4175
|
);
|
|
4251
4176
|
};
|
|
4252
4177
|
var VStack = (props) => /* @__PURE__ */ jsxRuntime.jsx(Stack, { direction: "vertical", ...props });
|
|
@@ -5163,9 +5088,17 @@ function getEntity(orbital) {
|
|
|
5163
5088
|
if (typeof entity === "string") {
|
|
5164
5089
|
return { name: entity, fields: [], persistence: "runtime" };
|
|
5165
5090
|
}
|
|
5091
|
+
if ("extends" in entity) {
|
|
5092
|
+
const ec = entity;
|
|
5093
|
+
return {
|
|
5094
|
+
name: ec.name ?? orbital.name,
|
|
5095
|
+
fields: ec.fields ?? [],
|
|
5096
|
+
persistence: ec.persistence ?? "runtime"
|
|
5097
|
+
};
|
|
5098
|
+
}
|
|
5166
5099
|
const e = entity;
|
|
5167
5100
|
return {
|
|
5168
|
-
name: e.name
|
|
5101
|
+
name: e.name,
|
|
5169
5102
|
fields: e.fields ?? [],
|
|
5170
5103
|
persistence: e.persistence ?? "runtime"
|
|
5171
5104
|
};
|
|
@@ -5174,6 +5107,7 @@ function getTraits(orbital) {
|
|
|
5174
5107
|
if (!orbital.traits) return [];
|
|
5175
5108
|
return orbital.traits.map((t) => {
|
|
5176
5109
|
if (typeof t === "string") return { name: t };
|
|
5110
|
+
if ("ref" in t && !("stateMachine" in t)) return { name: t.name ?? t.ref };
|
|
5177
5111
|
return t;
|
|
5178
5112
|
});
|
|
5179
5113
|
}
|
|
@@ -5181,6 +5115,7 @@ function getPages(orbital) {
|
|
|
5181
5115
|
if (!orbital.pages) return [];
|
|
5182
5116
|
return orbital.pages.map((p) => {
|
|
5183
5117
|
if (typeof p === "string") return { name: p, path: `/${p.toLowerCase()}` };
|
|
5118
|
+
if ("ref" in p && !("path" in p)) return { name: p.ref, path: `/${p.ref.toLowerCase()}` };
|
|
5184
5119
|
return p;
|
|
5185
5120
|
});
|
|
5186
5121
|
}
|
|
@@ -5199,12 +5134,12 @@ function getEvents(sm) {
|
|
|
5199
5134
|
function getEmits(trait) {
|
|
5200
5135
|
const emits = trait.emits;
|
|
5201
5136
|
if (!emits) return [];
|
|
5202
|
-
return emits.map((e) =>
|
|
5137
|
+
return emits.map((e) => e.event ?? "");
|
|
5203
5138
|
}
|
|
5204
5139
|
function getListens(trait) {
|
|
5205
5140
|
const listens = trait.listens;
|
|
5206
5141
|
if (!listens) return [];
|
|
5207
|
-
return listens.map((l) =>
|
|
5142
|
+
return listens.map((l) => l.event ?? "");
|
|
5208
5143
|
}
|
|
5209
5144
|
function parseEffectType(effect) {
|
|
5210
5145
|
if (Array.isArray(effect)) {
|
|
@@ -5375,14 +5310,14 @@ function parseTraitLevel(schema, orbitalName, traitName) {
|
|
|
5375
5310
|
if (!sm) return null;
|
|
5376
5311
|
const states = getStates(sm).map((s) => ({
|
|
5377
5312
|
name: s.name ?? "",
|
|
5378
|
-
isInitial: s.isInitial ??
|
|
5379
|
-
isTerminal: s.isTerminal ??
|
|
5313
|
+
isInitial: s.isInitial ?? null,
|
|
5314
|
+
isTerminal: s.isTerminal ?? null
|
|
5380
5315
|
}));
|
|
5381
5316
|
const transitions = getTransitions(sm).map((t, i) => ({
|
|
5382
5317
|
from: t.from ?? "",
|
|
5383
5318
|
to: t.to ?? "",
|
|
5384
5319
|
event: t.event ?? "",
|
|
5385
|
-
guard: t.guard,
|
|
5320
|
+
guard: t.guard ?? null,
|
|
5386
5321
|
effects: (t.effects ?? []).map(parseEffectType),
|
|
5387
5322
|
index: i
|
|
5388
5323
|
}));
|
|
@@ -5401,13 +5336,14 @@ function parseTransitionLevel(schema, orbitalName, traitName, transitionIndex) {
|
|
|
5401
5336
|
if (!traitData) return null;
|
|
5402
5337
|
const transition = traitData.transitions[transitionIndex];
|
|
5403
5338
|
if (!transition) return null;
|
|
5404
|
-
const
|
|
5339
|
+
const guardVal = transition.guard;
|
|
5340
|
+
const guard = guardVal != null ? exprToTree(guardVal) : null;
|
|
5405
5341
|
const effects = transition.effects.map(
|
|
5406
5342
|
(e) => exprToTree([e.type, ...e.args])
|
|
5407
5343
|
);
|
|
5408
5344
|
const slotTargets = transition.effects.filter((e) => e.type === "render-ui").map((e) => ({
|
|
5409
5345
|
name: String(e.args[0] ?? "main"),
|
|
5410
|
-
pattern: typeof e.args[1] === "object" && e.args[1] !== null ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
|
|
5346
|
+
pattern: typeof e.args[1] === "object" && e.args[1] !== null && !Array.isArray(e.args[1]) ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
|
|
5411
5347
|
}));
|
|
5412
5348
|
return {
|
|
5413
5349
|
from: transition.from,
|
|
@@ -6870,8 +6806,8 @@ var Avl3DTraitScene = ({
|
|
|
6870
6806
|
Avl3DStateNode,
|
|
6871
6807
|
{
|
|
6872
6808
|
name: state.name,
|
|
6873
|
-
isInitial: state.isInitial,
|
|
6874
|
-
isTerminal: state.isTerminal,
|
|
6809
|
+
isInitial: state.isInitial ?? void 0,
|
|
6810
|
+
isTerminal: state.isTerminal ?? void 0,
|
|
6875
6811
|
position: pos,
|
|
6876
6812
|
incomingCount: transitionCounts.incoming.get(state.name) ?? 0,
|
|
6877
6813
|
outgoingCount: transitionCounts.outgoing.get(state.name) ?? 0
|
|
@@ -2269,13 +2269,6 @@ function preloadFeatures(urls) {
|
|
|
2269
2269
|
}
|
|
2270
2270
|
|
|
2271
2271
|
// components/game/organisms/utils/spriteAnimation.ts
|
|
2272
|
-
function inferDirection(dx, dy) {
|
|
2273
|
-
if (dx === 0 && dy === 0) return "se";
|
|
2274
|
-
if (dx >= 0 && dy >= 0) return "se";
|
|
2275
|
-
if (dx <= 0 && dy >= 0) return "sw";
|
|
2276
|
-
if (dx >= 0 && dy <= 0) return "ne";
|
|
2277
|
-
return "nw";
|
|
2278
|
-
}
|
|
2279
2272
|
function resolveSheetDirection(facing) {
|
|
2280
2273
|
switch (facing) {
|
|
2281
2274
|
case "se":
|
|
@@ -2296,22 +2289,8 @@ function frameRect(frame, row, columns, frameWidth, frameHeight) {
|
|
|
2296
2289
|
sh: frameHeight
|
|
2297
2290
|
};
|
|
2298
2291
|
}
|
|
2299
|
-
function getCurrentFrameFromDef(def, elapsed) {
|
|
2300
|
-
const frameDuration = 1e3 / def.frameRate;
|
|
2301
|
-
const totalDuration = def.frames * frameDuration;
|
|
2302
|
-
if (def.loop) {
|
|
2303
|
-
const frame2 = Math.floor(elapsed % totalDuration / frameDuration);
|
|
2304
|
-
return { frame: frame2, finished: false };
|
|
2305
|
-
}
|
|
2306
|
-
if (elapsed >= totalDuration) {
|
|
2307
|
-
return { frame: def.frames - 1, finished: true };
|
|
2308
|
-
}
|
|
2309
|
-
const frame = Math.floor(elapsed / frameDuration);
|
|
2310
|
-
return { frame, finished: false };
|
|
2311
|
-
}
|
|
2312
2292
|
|
|
2313
2293
|
// components/game/molecules/useUnitSpriteAtlas.ts
|
|
2314
|
-
var WALK_HOLD_MS = 600;
|
|
2315
2294
|
function unitAtlasUrl(unit) {
|
|
2316
2295
|
if (unit.spriteSheet) return unit.spriteSheet;
|
|
2317
2296
|
const sprite = unit.sprite;
|
|
@@ -2333,9 +2312,6 @@ function useUnitSpriteAtlas(units) {
|
|
|
2333
2312
|
const loadingRef = useRef(/* @__PURE__ */ new Set());
|
|
2334
2313
|
const [pendingCount, setPendingCount] = useState(0);
|
|
2335
2314
|
const [, forceTick] = useState(0);
|
|
2336
|
-
const animStatesRef = useRef(/* @__PURE__ */ new Map());
|
|
2337
|
-
const lastTickRef = useRef(0);
|
|
2338
|
-
const rafRef = useRef(0);
|
|
2339
2315
|
const atlasUrls = useMemo(() => {
|
|
2340
2316
|
const set = /* @__PURE__ */ new Set();
|
|
2341
2317
|
for (const unit of units) {
|
|
@@ -2381,54 +2357,6 @@ function useUnitSpriteAtlas(units) {
|
|
|
2381
2357
|
}
|
|
2382
2358
|
return [...urls];
|
|
2383
2359
|
}, [units, pendingCount]);
|
|
2384
|
-
useEffect(() => {
|
|
2385
|
-
const hasAtlasUnits = units.some((u) => unitAtlasUrl(u) !== null);
|
|
2386
|
-
if (!hasAtlasUnits) return;
|
|
2387
|
-
let running = true;
|
|
2388
|
-
const tick = (ts) => {
|
|
2389
|
-
if (!running) return;
|
|
2390
|
-
const last = lastTickRef.current || ts;
|
|
2391
|
-
const delta = ts - last;
|
|
2392
|
-
lastTickRef.current = ts;
|
|
2393
|
-
const states = animStatesRef.current;
|
|
2394
|
-
const currentIds = /* @__PURE__ */ new Set();
|
|
2395
|
-
for (const unit of units) {
|
|
2396
|
-
if (unitAtlasUrl(unit) === null) continue;
|
|
2397
|
-
currentIds.add(unit.id);
|
|
2398
|
-
let state = states.get(unit.id);
|
|
2399
|
-
if (!state) {
|
|
2400
|
-
state = { animation: "idle", direction: "se", elapsed: 0, walkHold: 0, prev: null };
|
|
2401
|
-
states.set(unit.id, state);
|
|
2402
|
-
}
|
|
2403
|
-
const posX = unit.position?.x ?? unit.x ?? 0;
|
|
2404
|
-
const posY = unit.position?.y ?? unit.y ?? 0;
|
|
2405
|
-
if (state.prev) {
|
|
2406
|
-
const dx = posX - state.prev.x;
|
|
2407
|
-
const dy = posY - state.prev.y;
|
|
2408
|
-
if (dx !== 0 || dy !== 0) {
|
|
2409
|
-
state.animation = "walk";
|
|
2410
|
-
state.direction = inferDirection(dx, dy);
|
|
2411
|
-
state.walkHold = WALK_HOLD_MS;
|
|
2412
|
-
} else if (state.animation === "walk") {
|
|
2413
|
-
state.walkHold -= delta;
|
|
2414
|
-
if (state.walkHold <= 0) state.animation = "idle";
|
|
2415
|
-
}
|
|
2416
|
-
}
|
|
2417
|
-
state.prev = { x: posX, y: posY };
|
|
2418
|
-
state.elapsed += delta;
|
|
2419
|
-
}
|
|
2420
|
-
for (const id of states.keys()) {
|
|
2421
|
-
if (!currentIds.has(id)) states.delete(id);
|
|
2422
|
-
}
|
|
2423
|
-
rafRef.current = requestAnimationFrame(tick);
|
|
2424
|
-
};
|
|
2425
|
-
rafRef.current = requestAnimationFrame(tick);
|
|
2426
|
-
return () => {
|
|
2427
|
-
running = false;
|
|
2428
|
-
cancelAnimationFrame(rafRef.current);
|
|
2429
|
-
lastTickRef.current = 0;
|
|
2430
|
-
};
|
|
2431
|
-
}, [units]);
|
|
2432
2360
|
const resolveUnitFrame = useCallback((unitId) => {
|
|
2433
2361
|
const unit = units.find((u) => u.id === unitId);
|
|
2434
2362
|
if (!unit) return null;
|
|
@@ -2436,18 +2364,14 @@ function useUnitSpriteAtlas(units) {
|
|
|
2436
2364
|
if (!atlasUrl) return null;
|
|
2437
2365
|
const atlas = atlasCacheRef.current.get(atlasUrl);
|
|
2438
2366
|
if (!atlas) return null;
|
|
2439
|
-
const
|
|
2440
|
-
const
|
|
2441
|
-
const direction = state?.direction ?? "se";
|
|
2442
|
-
const elapsed = state?.elapsed ?? 0;
|
|
2367
|
+
const animation = unit.animation ?? "idle";
|
|
2368
|
+
const frame = unit.frame ?? 0;
|
|
2443
2369
|
const def = atlas.animations[animation] ?? atlas.animations.idle;
|
|
2444
2370
|
if (!def) return null;
|
|
2445
|
-
const { sheetDir, flipX } = resolveSheetDirection(
|
|
2371
|
+
const { sheetDir, flipX } = resolveSheetDirection("se");
|
|
2446
2372
|
const rel = atlas.sheets[sheetDir] ?? atlas.sheets.se ?? atlas.sheets.sw;
|
|
2447
2373
|
if (!rel) return null;
|
|
2448
2374
|
const sheetUrl = resolveSheetUrl(atlasUrl, rel);
|
|
2449
|
-
const isIdle = animation === "idle";
|
|
2450
|
-
const frame = isIdle ? 0 : getCurrentFrameFromDef(def, elapsed).frame;
|
|
2451
2375
|
const rect = frameRect(frame, def.row, atlas.columns, atlas.frameWidth, atlas.frameHeight);
|
|
2452
2376
|
return {
|
|
2453
2377
|
sheetUrl,
|
|
@@ -2456,7 +2380,7 @@ function useUnitSpriteAtlas(units) {
|
|
|
2456
2380
|
sw: rect.sw,
|
|
2457
2381
|
sh: rect.sh,
|
|
2458
2382
|
flipX,
|
|
2459
|
-
applyBreathing:
|
|
2383
|
+
applyBreathing: animation === "idle"
|
|
2460
2384
|
};
|
|
2461
2385
|
}, [units]);
|
|
2462
2386
|
return { sheetUrls, resolveUnitFrame, pendingCount };
|
|
@@ -2552,7 +2476,6 @@ var GameCanvas3D = forwardRef(
|
|
|
2552
2476
|
className,
|
|
2553
2477
|
isLoading: externalLoading,
|
|
2554
2478
|
error: externalError,
|
|
2555
|
-
entity,
|
|
2556
2479
|
preloadAssets = [],
|
|
2557
2480
|
tileClickEvent,
|
|
2558
2481
|
unitClickEvent,
|
|
@@ -3965,6 +3888,9 @@ var iconSizeStyles = {
|
|
|
3965
3888
|
md: "h-icon-default w-icon-default",
|
|
3966
3889
|
lg: "h-icon-default w-icon-default"
|
|
3967
3890
|
};
|
|
3891
|
+
function isIconLike(v) {
|
|
3892
|
+
return typeof v.render === "function";
|
|
3893
|
+
}
|
|
3968
3894
|
function resolveIconProp(value, sizeClass) {
|
|
3969
3895
|
if (!value) return null;
|
|
3970
3896
|
if (typeof value === "string") {
|
|
@@ -3977,7 +3903,7 @@ function resolveIconProp(value, sizeClass) {
|
|
|
3977
3903
|
if (React11.isValidElement(value)) {
|
|
3978
3904
|
return value;
|
|
3979
3905
|
}
|
|
3980
|
-
if (typeof value === "object" && value !== null &&
|
|
3906
|
+
if (typeof value === "object" && value !== null && isIconLike(value)) {
|
|
3981
3907
|
const IconComp = value;
|
|
3982
3908
|
return /* @__PURE__ */ jsx(IconComp, { className: sizeClass });
|
|
3983
3909
|
}
|
|
@@ -3999,6 +3925,7 @@ var Button = React11.forwardRef(
|
|
|
3999
3925
|
label,
|
|
4000
3926
|
children,
|
|
4001
3927
|
onClick,
|
|
3928
|
+
"data-testid": dataTestId,
|
|
4002
3929
|
...props
|
|
4003
3930
|
}, ref) => {
|
|
4004
3931
|
const eventBus = useEventBus();
|
|
@@ -4031,7 +3958,7 @@ var Button = React11.forwardRef(
|
|
|
4031
3958
|
),
|
|
4032
3959
|
onClick: handleClick,
|
|
4033
3960
|
...props,
|
|
4034
|
-
"data-testid":
|
|
3961
|
+
"data-testid": dataTestId ?? (action ? `action-${action}` : void 0),
|
|
4035
3962
|
children: [
|
|
4036
3963
|
isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-icon-default w-icon-default animate-spin" }) : resolvedLeftIcon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: resolvedLeftIcon }),
|
|
4037
3964
|
children || label,
|
|
@@ -4128,9 +4055,8 @@ var Typography = ({
|
|
|
4128
4055
|
}) => {
|
|
4129
4056
|
const variant = variantProp ?? (level ? `h${level}` : "body1");
|
|
4130
4057
|
const Component2 = as || defaultElements[variant];
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
Comp,
|
|
4058
|
+
return React11.createElement(
|
|
4059
|
+
Component2,
|
|
4134
4060
|
{
|
|
4135
4061
|
id,
|
|
4136
4062
|
className: cn(
|
|
@@ -4143,9 +4069,9 @@ var Typography = ({
|
|
|
4143
4069
|
overflow && overflowStyles[overflow],
|
|
4144
4070
|
className
|
|
4145
4071
|
),
|
|
4146
|
-
style
|
|
4147
|
-
|
|
4148
|
-
|
|
4072
|
+
style
|
|
4073
|
+
},
|
|
4074
|
+
children ?? content
|
|
4149
4075
|
);
|
|
4150
4076
|
};
|
|
4151
4077
|
Typography.displayName = "Typography";
|
|
@@ -4202,9 +4128,8 @@ var Stack = ({
|
|
|
4202
4128
|
};
|
|
4203
4129
|
const isHorizontal = direction === "horizontal";
|
|
4204
4130
|
const directionClass = responsive && isHorizontal ? reverse ? "flex-col-reverse md:flex-row-reverse" : "flex-col md:flex-row" : isHorizontal ? reverse ? "flex-row-reverse" : "flex-row" : reverse ? "flex-col-reverse" : "flex-col";
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
Comp,
|
|
4131
|
+
return React11.createElement(
|
|
4132
|
+
Component2,
|
|
4208
4133
|
{
|
|
4209
4134
|
className: cn(
|
|
4210
4135
|
"flex",
|
|
@@ -4220,9 +4145,9 @@ var Stack = ({
|
|
|
4220
4145
|
onClick: action || onClick ? handleClick : void 0,
|
|
4221
4146
|
onKeyDown,
|
|
4222
4147
|
role,
|
|
4223
|
-
tabIndex
|
|
4224
|
-
|
|
4225
|
-
|
|
4148
|
+
tabIndex
|
|
4149
|
+
},
|
|
4150
|
+
children
|
|
4226
4151
|
);
|
|
4227
4152
|
};
|
|
4228
4153
|
var VStack = (props) => /* @__PURE__ */ jsx(Stack, { direction: "vertical", ...props });
|
|
@@ -5139,9 +5064,17 @@ function getEntity(orbital) {
|
|
|
5139
5064
|
if (typeof entity === "string") {
|
|
5140
5065
|
return { name: entity, fields: [], persistence: "runtime" };
|
|
5141
5066
|
}
|
|
5067
|
+
if ("extends" in entity) {
|
|
5068
|
+
const ec = entity;
|
|
5069
|
+
return {
|
|
5070
|
+
name: ec.name ?? orbital.name,
|
|
5071
|
+
fields: ec.fields ?? [],
|
|
5072
|
+
persistence: ec.persistence ?? "runtime"
|
|
5073
|
+
};
|
|
5074
|
+
}
|
|
5142
5075
|
const e = entity;
|
|
5143
5076
|
return {
|
|
5144
|
-
name: e.name
|
|
5077
|
+
name: e.name,
|
|
5145
5078
|
fields: e.fields ?? [],
|
|
5146
5079
|
persistence: e.persistence ?? "runtime"
|
|
5147
5080
|
};
|
|
@@ -5150,6 +5083,7 @@ function getTraits(orbital) {
|
|
|
5150
5083
|
if (!orbital.traits) return [];
|
|
5151
5084
|
return orbital.traits.map((t) => {
|
|
5152
5085
|
if (typeof t === "string") return { name: t };
|
|
5086
|
+
if ("ref" in t && !("stateMachine" in t)) return { name: t.name ?? t.ref };
|
|
5153
5087
|
return t;
|
|
5154
5088
|
});
|
|
5155
5089
|
}
|
|
@@ -5157,6 +5091,7 @@ function getPages(orbital) {
|
|
|
5157
5091
|
if (!orbital.pages) return [];
|
|
5158
5092
|
return orbital.pages.map((p) => {
|
|
5159
5093
|
if (typeof p === "string") return { name: p, path: `/${p.toLowerCase()}` };
|
|
5094
|
+
if ("ref" in p && !("path" in p)) return { name: p.ref, path: `/${p.ref.toLowerCase()}` };
|
|
5160
5095
|
return p;
|
|
5161
5096
|
});
|
|
5162
5097
|
}
|
|
@@ -5175,12 +5110,12 @@ function getEvents(sm) {
|
|
|
5175
5110
|
function getEmits(trait) {
|
|
5176
5111
|
const emits = trait.emits;
|
|
5177
5112
|
if (!emits) return [];
|
|
5178
|
-
return emits.map((e) =>
|
|
5113
|
+
return emits.map((e) => e.event ?? "");
|
|
5179
5114
|
}
|
|
5180
5115
|
function getListens(trait) {
|
|
5181
5116
|
const listens = trait.listens;
|
|
5182
5117
|
if (!listens) return [];
|
|
5183
|
-
return listens.map((l) =>
|
|
5118
|
+
return listens.map((l) => l.event ?? "");
|
|
5184
5119
|
}
|
|
5185
5120
|
function parseEffectType(effect) {
|
|
5186
5121
|
if (Array.isArray(effect)) {
|
|
@@ -5351,14 +5286,14 @@ function parseTraitLevel(schema, orbitalName, traitName) {
|
|
|
5351
5286
|
if (!sm) return null;
|
|
5352
5287
|
const states = getStates(sm).map((s) => ({
|
|
5353
5288
|
name: s.name ?? "",
|
|
5354
|
-
isInitial: s.isInitial ??
|
|
5355
|
-
isTerminal: s.isTerminal ??
|
|
5289
|
+
isInitial: s.isInitial ?? null,
|
|
5290
|
+
isTerminal: s.isTerminal ?? null
|
|
5356
5291
|
}));
|
|
5357
5292
|
const transitions = getTransitions(sm).map((t, i) => ({
|
|
5358
5293
|
from: t.from ?? "",
|
|
5359
5294
|
to: t.to ?? "",
|
|
5360
5295
|
event: t.event ?? "",
|
|
5361
|
-
guard: t.guard,
|
|
5296
|
+
guard: t.guard ?? null,
|
|
5362
5297
|
effects: (t.effects ?? []).map(parseEffectType),
|
|
5363
5298
|
index: i
|
|
5364
5299
|
}));
|
|
@@ -5377,13 +5312,14 @@ function parseTransitionLevel(schema, orbitalName, traitName, transitionIndex) {
|
|
|
5377
5312
|
if (!traitData) return null;
|
|
5378
5313
|
const transition = traitData.transitions[transitionIndex];
|
|
5379
5314
|
if (!transition) return null;
|
|
5380
|
-
const
|
|
5315
|
+
const guardVal = transition.guard;
|
|
5316
|
+
const guard = guardVal != null ? exprToTree(guardVal) : null;
|
|
5381
5317
|
const effects = transition.effects.map(
|
|
5382
5318
|
(e) => exprToTree([e.type, ...e.args])
|
|
5383
5319
|
);
|
|
5384
5320
|
const slotTargets = transition.effects.filter((e) => e.type === "render-ui").map((e) => ({
|
|
5385
5321
|
name: String(e.args[0] ?? "main"),
|
|
5386
|
-
pattern: typeof e.args[1] === "object" && e.args[1] !== null ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
|
|
5322
|
+
pattern: typeof e.args[1] === "object" && e.args[1] !== null && !Array.isArray(e.args[1]) ? e.args[1].type ?? "unknown" : String(e.args[1] ?? "unknown")
|
|
5387
5323
|
}));
|
|
5388
5324
|
return {
|
|
5389
5325
|
from: transition.from,
|
|
@@ -6846,8 +6782,8 @@ var Avl3DTraitScene = ({
|
|
|
6846
6782
|
Avl3DStateNode,
|
|
6847
6783
|
{
|
|
6848
6784
|
name: state.name,
|
|
6849
|
-
isInitial: state.isInitial,
|
|
6850
|
-
isTerminal: state.isTerminal,
|
|
6785
|
+
isInitial: state.isInitial ?? void 0,
|
|
6786
|
+
isTerminal: state.isTerminal ?? void 0,
|
|
6851
6787
|
position: pos,
|
|
6852
6788
|
incomingCount: transitionCounts.incoming.get(state.name) ?? 0,
|
|
6853
6789
|
outgoingCount: transitionCounts.outgoing.get(state.name) ?? 0
|
|
@@ -23,8 +23,9 @@ export interface UseUnitSpriteAtlasResult {
|
|
|
23
23
|
pendingCount: number;
|
|
24
24
|
}
|
|
25
25
|
/**
|
|
26
|
-
* Load per-unit sprite atlases and
|
|
26
|
+
* Load per-unit sprite atlases and expose a pure frame resolver.
|
|
27
|
+
* Frame is computed from each unit's own `animation` + `frame` props — no internal clock.
|
|
27
28
|
*
|
|
28
|
-
* @param units - Units
|
|
29
|
+
* @param units - Units whose atlases should be loaded.
|
|
29
30
|
*/
|
|
30
31
|
export declare function useUnitSpriteAtlas(units: IsometricUnit[]): UseUnitSpriteAtlasResult;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { AssetUrl, EventEmit } from '@almadar/core';
|
|
2
|
+
import type { AssetUrl, EventEmit, EntityRow } from '@almadar/core';
|
|
3
3
|
import type { DisplayStateProps } from '../../core/organisms/types';
|
|
4
4
|
export interface PinballBoardProps extends DisplayStateProps {
|
|
5
5
|
/** Playfield tiles */
|
|
6
|
-
tiles?:
|
|
6
|
+
tiles?: readonly EntityRow[];
|
|
7
7
|
/** Ball units on the board */
|
|
8
|
-
units?:
|
|
8
|
+
units?: readonly EntityRow[];
|
|
9
9
|
/** Features (bumpers, paddles, etc.) on the board */
|
|
10
|
-
features?:
|
|
10
|
+
features?: readonly EntityRow[];
|
|
11
11
|
/** Asset sprite manifest */
|
|
12
12
|
assetManifest?: string;
|
|
13
13
|
/** Base URL prepended to manifest sprite paths */
|