@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.
Files changed (71) hide show
  1. package/dist/avl/index.cjs +253 -49
  2. package/dist/avl/index.css +3 -3
  3. package/dist/avl/index.js +255 -51
  4. package/dist/components/core/atoms/AtlasImage.d.ts +2 -2
  5. package/dist/components/core/atoms/FlipContainer.d.ts +1 -1
  6. package/dist/components/core/molecules/Card.d.ts +1 -1
  7. package/dist/components/core/molecules/Chart.d.ts +3 -3
  8. package/dist/components/core/molecules/DataGrid.d.ts +1 -1
  9. package/dist/components/core/molecules/DataList.d.ts +1 -1
  10. package/dist/components/core/molecules/DocPagination.d.ts +8 -1
  11. package/dist/components/core/molecules/DocSearch.d.ts +8 -1
  12. package/dist/components/core/molecules/FlipCard.d.ts +1 -1
  13. package/dist/components/core/molecules/LineChart.d.ts +3 -1
  14. package/dist/components/core/molecules/MapView.d.ts +18 -1
  15. package/dist/components/core/molecules/SortableList.d.ts +1 -1
  16. package/dist/components/core/molecules/TableView.d.ts +1 -1
  17. package/dist/components/core/organisms/DataTable.d.ts +7 -3
  18. package/dist/components/core/organisms/debug/RuntimeDebugger.d.ts +10 -1
  19. package/dist/components/core/organisms/debug/tabs/EntitiesTab.d.ts +2 -1
  20. package/dist/components/core/organisms/debug/tabs/EventDispatcherTab.d.ts +2 -1
  21. package/dist/components/core/organisms/debug/tabs/EventFlowTab.d.ts +6 -1
  22. package/dist/components/core/organisms/debug/tabs/GuardsPanel.d.ts +6 -1
  23. package/dist/components/core/organisms/debug/tabs/ServerBridgeTab.d.ts +12 -1
  24. package/dist/components/core/organisms/debug/tabs/TicksTab.d.ts +2 -1
  25. package/dist/components/core/organisms/debug/tabs/TraitsTab.d.ts +2 -1
  26. package/dist/components/core/organisms/debug/tabs/TransitionTimeline.d.ts +11 -1
  27. package/dist/components/core/organisms/debug/tabs/VerificationTab.d.ts +8 -1
  28. package/dist/components/game/2d/atoms/ActionButton.d.ts +2 -1
  29. package/dist/components/game/2d/atoms/ChoiceButton.d.ts +2 -1
  30. package/dist/components/game/2d/atoms/ComboCounter.d.ts +2 -1
  31. package/dist/components/game/2d/atoms/ControlButton.d.ts +2 -1
  32. package/dist/components/game/2d/atoms/DamageNumber.d.ts +2 -1
  33. package/dist/components/game/2d/atoms/DialogueBubble.d.ts +2 -1
  34. package/dist/components/game/2d/atoms/GameIcon.d.ts +2 -1
  35. package/dist/components/game/2d/atoms/HealthBar.d.ts +2 -1
  36. package/dist/components/game/2d/atoms/ItemSlot.d.ts +2 -1
  37. package/dist/components/game/2d/atoms/MiniMap.d.ts +2 -1
  38. package/dist/components/game/2d/atoms/ResourceCounter.d.ts +2 -1
  39. package/dist/components/game/2d/atoms/ScoreDisplay.d.ts +2 -1
  40. package/dist/components/game/2d/atoms/StatusEffect.d.ts +2 -1
  41. package/dist/components/game/2d/atoms/TimerDisplay.d.ts +2 -1
  42. package/dist/components/game/2d/atoms/TurnIndicator.d.ts +2 -1
  43. package/dist/components/game/2d/atoms/WaypointMarker.d.ts +2 -1
  44. package/dist/components/game/2d/molecules/Canvas2D.d.ts +5 -4
  45. package/dist/components/game/2d/molecules/GameHud.d.ts +2 -1
  46. package/dist/components/game/2d/molecules/GameMenu.d.ts +2 -1
  47. package/dist/components/game/2d/molecules/InventoryGrid.d.ts +2 -1
  48. package/dist/components/game/2d/molecules/ResourceBar.d.ts +2 -1
  49. package/dist/components/game/2d/molecules/StatBadge.d.ts +2 -1
  50. package/dist/components/game/shared/lib/editorUtils.d.ts +8 -8
  51. package/dist/components/index.cjs +100 -24
  52. package/dist/components/index.css +3 -3
  53. package/dist/components/index.js +85 -13
  54. package/dist/hooks/index.cjs +71 -0
  55. package/dist/hooks/index.d.ts +1 -0
  56. package/dist/hooks/index.js +69 -2
  57. package/dist/hooks/useGitHub.d.ts +7 -7
  58. package/dist/hooks/useSharedEntityStore.d.ts +53 -0
  59. package/dist/hooks/useTraitStateMachine.d.ts +32 -1
  60. package/dist/marketing/index.cjs +2 -2
  61. package/dist/marketing/index.js +2 -2
  62. package/dist/providers/EventBusProvider.d.ts +1 -1
  63. package/dist/providers/SelectionProvider.d.ts +1 -1
  64. package/dist/providers/ServerBridge.d.ts +1 -1
  65. package/dist/providers/index.cjs +11 -5
  66. package/dist/providers/index.css +3 -3
  67. package/dist/providers/index.js +11 -5
  68. package/dist/runtime/index.cjs +253 -49
  69. package/dist/runtime/index.css +3 -3
  70. package/dist/runtime/index.js +255 -51
  71. package/package.json +11 -16
@@ -3,6 +3,7 @@
3
3
  var react = require('react');
4
4
  var logger = require('@almadar/logger');
5
5
  var providers = require('@almadar/ui/providers');
6
+ var core = require('@almadar/core');
6
7
  var reactQuery = require('@tanstack/react-query');
7
8
 
8
9
  var log = logger.createLogger("almadar:ui:orbital-history");
@@ -1405,6 +1406,72 @@ function useTraitListens(dispatch, listens, eventBusInstance) {
1405
1406
  };
1406
1407
  }, [eventBus, dispatch, stableListens]);
1407
1408
  }
1409
+ var log12 = logger.createLogger("almadar:ui:shared-entity-store");
1410
+ var EMPTY_ENTITY_STATE = {};
1411
+ function createSharedEntityStore() {
1412
+ const states = /* @__PURE__ */ new Map();
1413
+ const subscribers = /* @__PURE__ */ new Map();
1414
+ const getSnapshot = (entityId) => states.get(entityId) ?? EMPTY_ENTITY_STATE;
1415
+ const subscribe = (entityId, callback) => {
1416
+ let set = subscribers.get(entityId);
1417
+ if (!set) {
1418
+ set = /* @__PURE__ */ new Set();
1419
+ subscribers.set(entityId, set);
1420
+ }
1421
+ set.add(callback);
1422
+ return () => {
1423
+ const current = subscribers.get(entityId);
1424
+ if (!current) return;
1425
+ current.delete(callback);
1426
+ if (current.size === 0) {
1427
+ subscribers.delete(entityId);
1428
+ }
1429
+ };
1430
+ };
1431
+ const commit = (entityId, nextState) => {
1432
+ states.set(entityId, nextState);
1433
+ const set = subscribers.get(entityId);
1434
+ if (!set) return;
1435
+ set.forEach((callback) => {
1436
+ try {
1437
+ callback();
1438
+ } catch (error) {
1439
+ log12.error("Shared entity subscriber error", {
1440
+ entityId,
1441
+ error: error instanceof Error ? error : String(error)
1442
+ });
1443
+ }
1444
+ });
1445
+ };
1446
+ const seed = (entityId, initialState) => {
1447
+ if (!states.has(entityId)) {
1448
+ states.set(entityId, initialState);
1449
+ }
1450
+ };
1451
+ return { getSnapshot, subscribe, commit, seed };
1452
+ }
1453
+ function useSharedEntityStore() {
1454
+ const storeRef = react.useRef(null);
1455
+ if (storeRef.current === null) {
1456
+ storeRef.current = createSharedEntityStore();
1457
+ }
1458
+ return storeRef.current;
1459
+ }
1460
+ function useSharedEntitySnapshot(store, entityId) {
1461
+ return react.useSyncExternalStore(
1462
+ (onStoreChange) => store.subscribe(entityId, onStoreChange),
1463
+ () => store.getSnapshot(entityId)
1464
+ );
1465
+ }
1466
+ function runTickFrame(entityId, orderedWriters, store) {
1467
+ let scratch = store.getSnapshot(entityId);
1468
+ for (const writer of orderedWriters) {
1469
+ const writes = writer(scratch);
1470
+ scratch = core.mergeEntityFrame(scratch, writes);
1471
+ }
1472
+ store.commit(entityId, scratch);
1473
+ return scratch;
1474
+ }
1408
1475
  var queryStores = /* @__PURE__ */ new Map();
1409
1476
  function getOrCreateStore(query) {
1410
1477
  if (!queryStores.has(query)) {
@@ -2740,8 +2807,10 @@ function useGitHubBranches(owner, repo, enabled = true) {
2740
2807
  exports.ALMADAR_DND_MIME = ALMADAR_DND_MIME;
2741
2808
  exports.DEFAULT_SLOTS = DEFAULT_SLOTS;
2742
2809
  exports.I18nProvider = I18nProvider;
2810
+ exports.createSharedEntityStore = createSharedEntityStore;
2743
2811
  exports.createTranslate = createTranslate;
2744
2812
  exports.parseQueryBinding = parseQueryBinding;
2813
+ exports.runTickFrame = runTickFrame;
2745
2814
  exports.useAgentChat = useAgentChat;
2746
2815
  exports.useAuthContext = useAuthContext;
2747
2816
  exports.useCanvasGestures = useCanvasGestures;
@@ -2769,6 +2838,8 @@ exports.usePreview = usePreview;
2769
2838
  exports.usePullToRefresh = usePullToRefresh;
2770
2839
  exports.useQuerySingleton = useQuerySingleton;
2771
2840
  exports.useRenderInterpolation = useRenderInterpolation;
2841
+ exports.useSharedEntitySnapshot = useSharedEntitySnapshot;
2842
+ exports.useSharedEntityStore = useSharedEntityStore;
2772
2843
  exports.useSwipeGesture = useSwipeGesture;
2773
2844
  exports.useTapReveal = useTapReveal;
2774
2845
  exports.useTraitListens = useTraitListens;
@@ -16,6 +16,7 @@ export type { BusEvent, BusEventSource, BusEventListener, Unsubscribe, EventBusC
16
16
  export type { BusEventListener as EventListener } from '../types/event-bus-types';
17
17
  export { useUISlotManager, DEFAULT_SLOTS, type UISlot, type SlotAnimation, type SlotContent, type SlotRenderConfig, type SlotChangeCallback, type UISlotManager, } from './useUISlots';
18
18
  export { useUIEvents, useTraitListens, type TraitListenSpec } from './useUIEvents';
19
+ export { createSharedEntityStore, useSharedEntityStore, useSharedEntitySnapshot, runTickFrame, type SharedEntityStore, type SharedEntitySubscriber, type SharedEntityWriter, } from './useSharedEntityStore';
19
20
  export { useQuerySingleton, parseQueryBinding, type QueryState, type QuerySingletonEntity, type QuerySingletonResult, type QuerySingletonState, } from './useQuerySingleton';
20
21
  export { useTranslate, I18nProvider, createTranslate, type TranslateFunction, type I18nContextValue, } from './useTranslate';
21
22
  export { useAuthContext, type AuthUser, type AuthContextValue, } from './useAuthContext';
@@ -1,6 +1,7 @@
1
- import { createContext, useCallback, useState, useEffect, useMemo, useContext, useRef } from 'react';
1
+ import { createContext, useCallback, useState, useEffect, useMemo, useContext, useRef, useSyncExternalStore } from 'react';
2
2
  import { createLogger } from '@almadar/logger';
3
3
  import { EventBusContext, useTraitScope } from '@almadar/ui/providers';
4
+ import { mergeEntityFrame } from '@almadar/core';
4
5
  import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query';
5
6
 
6
7
  var log = createLogger("almadar:ui:orbital-history");
@@ -1403,6 +1404,72 @@ function useTraitListens(dispatch, listens, eventBusInstance) {
1403
1404
  };
1404
1405
  }, [eventBus, dispatch, stableListens]);
1405
1406
  }
1407
+ var log12 = createLogger("almadar:ui:shared-entity-store");
1408
+ var EMPTY_ENTITY_STATE = {};
1409
+ function createSharedEntityStore() {
1410
+ const states = /* @__PURE__ */ new Map();
1411
+ const subscribers = /* @__PURE__ */ new Map();
1412
+ const getSnapshot = (entityId) => states.get(entityId) ?? EMPTY_ENTITY_STATE;
1413
+ const subscribe = (entityId, callback) => {
1414
+ let set = subscribers.get(entityId);
1415
+ if (!set) {
1416
+ set = /* @__PURE__ */ new Set();
1417
+ subscribers.set(entityId, set);
1418
+ }
1419
+ set.add(callback);
1420
+ return () => {
1421
+ const current = subscribers.get(entityId);
1422
+ if (!current) return;
1423
+ current.delete(callback);
1424
+ if (current.size === 0) {
1425
+ subscribers.delete(entityId);
1426
+ }
1427
+ };
1428
+ };
1429
+ const commit = (entityId, nextState) => {
1430
+ states.set(entityId, nextState);
1431
+ const set = subscribers.get(entityId);
1432
+ if (!set) return;
1433
+ set.forEach((callback) => {
1434
+ try {
1435
+ callback();
1436
+ } catch (error) {
1437
+ log12.error("Shared entity subscriber error", {
1438
+ entityId,
1439
+ error: error instanceof Error ? error : String(error)
1440
+ });
1441
+ }
1442
+ });
1443
+ };
1444
+ const seed = (entityId, initialState) => {
1445
+ if (!states.has(entityId)) {
1446
+ states.set(entityId, initialState);
1447
+ }
1448
+ };
1449
+ return { getSnapshot, subscribe, commit, seed };
1450
+ }
1451
+ function useSharedEntityStore() {
1452
+ const storeRef = useRef(null);
1453
+ if (storeRef.current === null) {
1454
+ storeRef.current = createSharedEntityStore();
1455
+ }
1456
+ return storeRef.current;
1457
+ }
1458
+ function useSharedEntitySnapshot(store, entityId) {
1459
+ return useSyncExternalStore(
1460
+ (onStoreChange) => store.subscribe(entityId, onStoreChange),
1461
+ () => store.getSnapshot(entityId)
1462
+ );
1463
+ }
1464
+ function runTickFrame(entityId, orderedWriters, store) {
1465
+ let scratch = store.getSnapshot(entityId);
1466
+ for (const writer of orderedWriters) {
1467
+ const writes = writer(scratch);
1468
+ scratch = mergeEntityFrame(scratch, writes);
1469
+ }
1470
+ store.commit(entityId, scratch);
1471
+ return scratch;
1472
+ }
1406
1473
  var queryStores = /* @__PURE__ */ new Map();
1407
1474
  function getOrCreateStore(query) {
1408
1475
  if (!queryStores.has(query)) {
@@ -2735,4 +2802,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
2735
2802
  });
2736
2803
  }
2737
2804
 
2738
- export { ALMADAR_DND_MIME, DEFAULT_SLOTS, I18nProvider, createTranslate, parseQueryBinding, useAgentChat, useAuthContext, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate, useUIEvents, useUISlotManager, useValidation };
2805
+ export { ALMADAR_DND_MIME, DEFAULT_SLOTS, I18nProvider, createSharedEntityStore, createTranslate, parseQueryBinding, runTickFrame, useAgentChat, useAuthContext, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSharedEntitySnapshot, useSharedEntityStore, useSwipeGesture, useTapReveal, useTraitListens, useTranslate, useUIEvents, useUISlotManager, useValidation };
@@ -25,7 +25,7 @@ export interface GitHubRepo {
25
25
  /**
26
26
  * Hook to get GitHub connection status
27
27
  */
28
- export declare function useGitHubStatus(): import("@tanstack/react-query").UseQueryResult<GitHubStatus, Error>;
28
+ export declare function useGitHubStatus(): import("@tanstack/react-query").UseQueryResult<NoInfer<GitHubStatus>, Error>;
29
29
  /**
30
30
  * Hook to connect GitHub (initiate OAuth flow)
31
31
  */
@@ -39,20 +39,20 @@ export declare function useDisconnectGitHub(): import("@tanstack/react-query").U
39
39
  /**
40
40
  * Hook to list GitHub repositories
41
41
  */
42
- export declare function useGitHubRepos(page?: number, perPage?: number): import("@tanstack/react-query").UseQueryResult<{
42
+ export declare function useGitHubRepos(page?: number, perPage?: number): import("@tanstack/react-query").UseQueryResult<NoInfer<{
43
43
  repos: GitHubRepo[];
44
44
  page: number;
45
45
  perPage: number;
46
- }, Error>;
46
+ }>, Error>;
47
47
  /**
48
48
  * Hook to get repository details
49
49
  */
50
- export declare function useGitHubRepo(owner: string, repo: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<{
50
+ export declare function useGitHubRepo(owner: string, repo: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<{
51
51
  repo: GitHubRepo;
52
- }, Error>;
52
+ }>, Error>;
53
53
  /**
54
54
  * Hook to list repository branches
55
55
  */
56
- export declare function useGitHubBranches(owner: string, repo: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<{
56
+ export declare function useGitHubBranches(owner: string, repo: string, enabled?: boolean): import("@tanstack/react-query").UseQueryResult<NoInfer<{
57
57
  branches: string[];
58
- }, Error>;
58
+ }>, Error>;
@@ -0,0 +1,53 @@
1
+ import type { EntityFieldWrite, EntityFrameState } from '@almadar/core';
2
+ /** Notification callback fired after a `commit()` for the subscribed entity id. */
3
+ export type SharedEntitySubscriber = () => void;
4
+ /**
5
+ * One writer trait's per-frame step: reads the live running scratch
6
+ * (reflecting every earlier writer's writes this frame) and returns its own
7
+ * field writes. Pure — writers never call `store.commit`; only `runTickFrame`
8
+ * does, once per frame.
9
+ */
10
+ export type SharedEntityWriter = (scratch: EntityFrameState) => readonly EntityFieldWrite[];
11
+ /** Manager surface, keyed by entity id. */
12
+ export interface SharedEntityStore {
13
+ getSnapshot: (entityId: string) => EntityFrameState;
14
+ subscribe: (entityId: string, callback: SharedEntitySubscriber) => () => void;
15
+ commit: (entityId: string, nextState: EntityFrameState) => void;
16
+ /**
17
+ * Set the initial state for an entity id, but ONLY if nothing is committed
18
+ * yet — idempotent, and (unlike `commit`) does NOT notify subscribers, so it
19
+ * is safe to call during render. Both execution paths seed from the entity's
20
+ * declared field defaults at init, so frame 0 reads the defaults on both.
21
+ */
22
+ seed: (entityId: string, initialState: EntityFrameState) => void;
23
+ }
24
+ /**
25
+ * Create a standalone shared-entity store. Plain factory — no React — so a
26
+ * clock owner (the interpreter's TickScheduler, or a codegen rAF
27
+ * `useEffect`) can hold one instance and pass it to `runTickFrame` without
28
+ * going through a hook.
29
+ */
30
+ export declare function createSharedEntityStore(): SharedEntityStore;
31
+ /**
32
+ * React hook: one stable `SharedEntityStore` instance for this component's
33
+ * lifetime (useUISlotManager's ref-backed-instance pattern — no re-creation
34
+ * across re-renders). Callers own one store per running orbital instance and
35
+ * thread it to each writer trait plus the render trait via `runTickFrame` /
36
+ * `useSharedEntitySnapshot`.
37
+ */
38
+ export declare function useSharedEntityStore(): SharedEntityStore;
39
+ /**
40
+ * Bridge one entity's snapshot into React via `useSyncExternalStore` (the
41
+ * codebase's established store->React bridge, see `lib/perf.ts`). The render
42
+ * trait re-renders exactly when `runTickFrame` commits this entity — never on
43
+ * an intermediate per-writer write, since those never call `store.commit`.
44
+ */
45
+ export declare function useSharedEntitySnapshot(store: SharedEntityStore, entityId: string): EntityFrameState;
46
+ /**
47
+ * Run one frame for `entityId`: fold each writer's writes into a running
48
+ * scratch in binding order via `mergeEntityFrame` (field-level, so writer
49
+ * k+1 reads writer k's same-frame writes), then commit the merged result
50
+ * exactly ONCE. Clock-agnostic — the caller (a TickScheduler tick or a
51
+ * codegen rAF loop) invokes this once per frame; it owns no timer itself.
52
+ */
53
+ export declare function runTickFrame(entityId: string, orderedWriters: readonly SharedEntityWriter[], store: SharedEntityStore): EntityFrameState;
@@ -16,7 +16,9 @@
16
16
  *
17
17
  * @packageDocumentation
18
18
  */
19
- import type { EventPayload, ServiceParams } from '@almadar/core';
19
+ import { type MutableRefObject } from 'react';
20
+ import { type SharedEntityWriter } from './index';
21
+ import type { ResolvedTraitTick, EventPayload, SExpr, ServiceParams, ResolvedTrait } from '@almadar/core';
20
22
  import { type TraitState } from '@almadar/runtime';
21
23
  import type { ResolvedTraitBinding } from '../types/runtime-types';
22
24
  import type { useUISlots } from '../providers/UISlotContext';
@@ -31,6 +33,35 @@ export interface TraitStateMachineResult {
31
33
  /** Check if a trait can handle an event from its current state */
32
34
  canHandleEvent: (traitName: string, eventKey: string) => boolean;
33
35
  }
36
+ /** Effect head-operator that writes a field onto a shared entity. */
37
+ export declare const SHARED_ENTITY_WRITE_OPS: ReadonlySet<string>;
38
+ /** Effect head-operators that paint a shared entity's merged state. */
39
+ export declare const SHARED_ENTITY_RENDER_OPS: ReadonlySet<string>;
40
+ /** Every tick + transition effect a trait declares, flattened for a structural scan. */
41
+ export declare function collectAllTraitEffects(trait: ResolvedTrait): SExpr[];
42
+ /**
43
+ * Does ANY effect in this list call one of `ops` anywhere in its (possibly
44
+ * `do`/`if`/`when`/`let`-nested) tree? Reuses `@almadar/core`'s canonical
45
+ * `walkSExpr` rather than a bespoke recursive walk, and looks only at the
46
+ * effect's head operator — a structural presence check, no name-matching.
47
+ */
48
+ export declare function effectsCallOp(effects: SExpr[], ops: ReadonlySet<string>): boolean;
49
+ /**
50
+ * Build one writer trait's tick into a synchronous `SharedEntityWriter`
51
+ * (`(scratch) => writes[]`) so `runTickFrame` can fold several writer ticks
52
+ * into one merged commit, in binding order.
53
+ *
54
+ * `runTickFrame`'s writer contract is synchronous, but `@almadar/runtime`'s
55
+ * `EffectExecutor` is inherently async (`executeAll`'s `for...of await`
56
+ * sequencing only guarantees the FIRST top-level effect lands before a
57
+ * fire-and-forget caller reads the result back — everything after the first
58
+ * `await` boundary would be silently dropped). `@almadar/evaluator`'s
59
+ * `executeEffects` is fully synchronous end-to-end (its `set`/`do`/`if`/
60
+ * `when`/`let` dispatch never awaits), so it — not `EffectExecutor` — is the
61
+ * correct tool here; `ctx.mutateEntity` captures each write instead of
62
+ * applying it through a handler.
63
+ */
64
+ export declare function createSharedEntityWriter(binding: ResolvedTraitBinding, tick: ResolvedTraitTick, traitStatesRef: MutableRefObject<Map<string, TraitState>>, emit: (event: string, payload?: EventPayload) => void): SharedEntityWriter;
34
65
  export interface UseTraitStateMachineOptions {
35
66
  /**
36
67
  * Callback invoked after each event is processed (for server forwarding).
@@ -26,7 +26,7 @@ function _interopNamespace(e) {
26
26
  var React12__namespace = /*#__PURE__*/_interopNamespace(React12);
27
27
  var LucideIcons2__namespace = /*#__PURE__*/_interopNamespace(LucideIcons2);
28
28
 
29
- // node_modules/clsx/dist/clsx.mjs
29
+ // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
30
30
  function r(e) {
31
31
  var t, f3, n = "";
32
32
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -41,7 +41,7 @@ function clsx() {
41
41
  return n;
42
42
  }
43
43
 
44
- // node_modules/tailwind-merge/dist/bundle-mjs.mjs
44
+ // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
45
45
  var CLASS_PART_SEPARATOR = "-";
46
46
  var createClassGroupUtils = (config) => {
47
47
  const classMap = createClassMap(config);
@@ -5,7 +5,7 @@ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import * as LucideIcons2 from 'lucide-react';
6
6
  import { Loader2, X } from 'lucide-react';
7
7
 
8
- // node_modules/clsx/dist/clsx.mjs
8
+ // node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
9
9
  function r(e) {
10
10
  var t, f3, n = "";
11
11
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -20,7 +20,7 @@ function clsx() {
20
20
  return n;
21
21
  }
22
22
 
23
- // node_modules/tailwind-merge/dist/bundle-mjs.mjs
23
+ // node_modules/.pnpm/tailwind-merge@2.6.1/node_modules/tailwind-merge/dist/bundle-mjs.mjs
24
24
  var CLASS_PART_SEPARATOR = "-";
25
25
  var createClassGroupUtils = (config) => {
26
26
  const classMap = createClassMap(config);
@@ -43,5 +43,5 @@ interface EventBusProviderProps {
43
43
  */
44
44
  isolated?: boolean;
45
45
  }
46
- export declare function EventBusProvider({ children, isolated }: EventBusProviderProps): import("react/jsx-runtime").JSX.Element;
46
+ export declare function EventBusProvider({ children, isolated }: EventBusProviderProps): React.JSX.Element;
47
47
  export type { EventBusContextType };
@@ -50,7 +50,7 @@ interface SelectionProviderProps {
50
50
  * }
51
51
  * ```
52
52
  */
53
- export declare function SelectionProvider({ children, debug, compareEntities, }: SelectionProviderProps): import("react/jsx-runtime").JSX.Element;
53
+ export declare function SelectionProvider({ children, debug, compareEntities, }: SelectionProviderProps): React.JSX.Element;
54
54
  /**
55
55
  * Hook to access selection state.
56
56
  *
@@ -98,5 +98,5 @@ export interface ServerBridgeProviderProps {
98
98
  transport?: ServerBridgeTransport;
99
99
  children: ReactNode;
100
100
  }
101
- export declare function ServerBridgeProvider({ schema, serverUrl, transport: customTransport, children, }: ServerBridgeProviderProps): import("react/jsx-runtime").JSX.Element;
101
+ export declare function ServerBridgeProvider({ schema, serverUrl, transport: customTransport, children, }: ServerBridgeProviderProps): import("react").JSX.Element;
102
102
  export {};
@@ -10248,6 +10248,9 @@ var init_useUnitSpriteAtlas = __esm({
10248
10248
  init_spriteAnimation();
10249
10249
  }
10250
10250
  });
10251
+ function normalizeBackdrop(bg) {
10252
+ return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
10253
+ }
10251
10254
  function SideView({
10252
10255
  player,
10253
10256
  platforms,
@@ -10257,7 +10260,7 @@ function SideView({
10257
10260
  canvasHeight,
10258
10261
  follow,
10259
10262
  bgColor,
10260
- backgroundImage,
10263
+ backgroundImage: backgroundImageRaw,
10261
10264
  playerSprite,
10262
10265
  tileSprites,
10263
10266
  effects,
@@ -10265,6 +10268,7 @@ function SideView({
10265
10268
  keyUpMap,
10266
10269
  className
10267
10270
  }) {
10271
+ const backgroundImage = normalizeBackdrop(backgroundImageRaw);
10268
10272
  const canvasRef = React98.useRef(null);
10269
10273
  const eventBus = useEventBus();
10270
10274
  const keysRef = React98.useRef(/* @__PURE__ */ new Set());
@@ -10556,7 +10560,7 @@ function Canvas2D({
10556
10560
  effects: _effectsPropRaw = [],
10557
10561
  platforms,
10558
10562
  player,
10559
- backgroundImage,
10563
+ backgroundImage: backgroundImageRaw,
10560
10564
  // Interaction state
10561
10565
  selectedUnitId = null,
10562
10566
  validMoves = [],
@@ -10597,6 +10601,7 @@ function Canvas2D({
10597
10601
  // Remote asset loading
10598
10602
  assetManifest
10599
10603
  }) {
10604
+ const backgroundImage = normalizeBackdrop(backgroundImageRaw);
10600
10605
  const isSide = projection === "side";
10601
10606
  const isFree = projection === "free";
10602
10607
  const flatLike = projection === "hex" || projection === "flat" || isFree;
@@ -17790,9 +17795,9 @@ var init_BiologyCanvas = __esm({
17790
17795
  }
17791
17796
  });
17792
17797
 
17793
- // node_modules/katex/dist/katex.min.css
17798
+ // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
17794
17799
  var init_katex_min = __esm({
17795
- "node_modules/katex/dist/katex.min.css"() {
17800
+ "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
17796
17801
  }
17797
17802
  });
17798
17803
  var Tabs;
@@ -29998,8 +30003,9 @@ var init_LineChart = __esm({
29998
30003
  const safeData = data ?? [];
29999
30004
  const sortedData = React98.useMemo(() => {
30000
30005
  if (safeData.length === 0) return [];
30006
+ if (!safeData.some((d) => d.date != null)) return [...safeData];
30001
30007
  return [...safeData].sort(
30002
- (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
30008
+ (a, b) => new Date(a.date ?? 0).getTime() - new Date(b.date ?? 0).getTime()
30003
30009
  );
30004
30010
  }, [safeData]);
30005
30011
  const points = React98.useMemo(() => {
@@ -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.45";
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;
@@ -10203,6 +10203,9 @@ var init_useUnitSpriteAtlas = __esm({
10203
10203
  init_spriteAnimation();
10204
10204
  }
10205
10205
  });
10206
+ function normalizeBackdrop(bg) {
10207
+ return typeof bg === "string" ? { url: bg, role: "decoration", category: "background" } : bg;
10208
+ }
10206
10209
  function SideView({
10207
10210
  player,
10208
10211
  platforms,
@@ -10212,7 +10215,7 @@ function SideView({
10212
10215
  canvasHeight,
10213
10216
  follow,
10214
10217
  bgColor,
10215
- backgroundImage,
10218
+ backgroundImage: backgroundImageRaw,
10216
10219
  playerSprite,
10217
10220
  tileSprites,
10218
10221
  effects,
@@ -10220,6 +10223,7 @@ function SideView({
10220
10223
  keyUpMap,
10221
10224
  className
10222
10225
  }) {
10226
+ const backgroundImage = normalizeBackdrop(backgroundImageRaw);
10223
10227
  const canvasRef = useRef(null);
10224
10228
  const eventBus = useEventBus();
10225
10229
  const keysRef = useRef(/* @__PURE__ */ new Set());
@@ -10511,7 +10515,7 @@ function Canvas2D({
10511
10515
  effects: _effectsPropRaw = [],
10512
10516
  platforms,
10513
10517
  player,
10514
- backgroundImage,
10518
+ backgroundImage: backgroundImageRaw,
10515
10519
  // Interaction state
10516
10520
  selectedUnitId = null,
10517
10521
  validMoves = [],
@@ -10552,6 +10556,7 @@ function Canvas2D({
10552
10556
  // Remote asset loading
10553
10557
  assetManifest
10554
10558
  }) {
10559
+ const backgroundImage = normalizeBackdrop(backgroundImageRaw);
10555
10560
  const isSide = projection === "side";
10556
10561
  const isFree = projection === "free";
10557
10562
  const flatLike = projection === "hex" || projection === "flat" || isFree;
@@ -17745,9 +17750,9 @@ var init_BiologyCanvas = __esm({
17745
17750
  }
17746
17751
  });
17747
17752
 
17748
- // node_modules/katex/dist/katex.min.css
17753
+ // node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css
17749
17754
  var init_katex_min = __esm({
17750
- "node_modules/katex/dist/katex.min.css"() {
17755
+ "node_modules/.pnpm/katex@0.16.47/node_modules/katex/dist/katex.min.css"() {
17751
17756
  }
17752
17757
  });
17753
17758
  var Tabs;
@@ -29953,8 +29958,9 @@ var init_LineChart = __esm({
29953
29958
  const safeData = data ?? [];
29954
29959
  const sortedData = useMemo(() => {
29955
29960
  if (safeData.length === 0) return [];
29961
+ if (!safeData.some((d) => d.date != null)) return [...safeData];
29956
29962
  return [...safeData].sort(
29957
- (a, b) => new Date(a.date).getTime() - new Date(b.date).getTime()
29963
+ (a, b) => new Date(a.date ?? 0).getTime() - new Date(b.date ?? 0).getTime()
29958
29964
  );
29959
29965
  }, [safeData]);
29960
29966
  const points = useMemo(() => {