@almadar/ui 2.28.2 → 2.30.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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import React8, { createContext, useCallback, useContext, useState, useMemo, useEffect, useReducer, useRef } from 'react';
2
+ import React8, { createContext, useCallback, useContext, useMemo, useState, useEffect, useReducer, useRef } from 'react';
3
3
  import '@react-three/drei';
4
4
  import '@react-three/fiber';
5
5
  import 'three';
@@ -5191,6 +5191,414 @@ var AvlSwimLane = ({
5191
5191
  ] });
5192
5192
  };
5193
5193
  AvlSwimLane.displayName = "AvlSwimLane";
5194
+ var DOMAIN_COLORS = {
5195
+ commerce: "#14b8a6",
5196
+ healthcare: "#3b82f6",
5197
+ education: "#6366f1",
5198
+ finance: "#10b981",
5199
+ scheduling: "#f59e0b",
5200
+ workflow: "#f97316",
5201
+ social: "#ec4899",
5202
+ media: "#a855f7",
5203
+ gaming: "#ef4444",
5204
+ iot: "#06b6d4",
5205
+ crm: "#0ea5e9",
5206
+ analytics: "#8b5cf6",
5207
+ communication: "#f43f5e",
5208
+ content: "#84cc16",
5209
+ location: "#22c55e",
5210
+ hr: "#64748b",
5211
+ legal: "#78716c",
5212
+ "real-estate": "#a8a29e"
5213
+ };
5214
+ var SIZE_MAP = {
5215
+ xs: 32,
5216
+ sm: 48,
5217
+ md: 120,
5218
+ lg: 200,
5219
+ xl: 300
5220
+ };
5221
+ function PersistenceCore({ cx, cy, r: r2, persistence, color }) {
5222
+ switch (persistence) {
5223
+ case "runtime":
5224
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5225
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: r2, fill: "none", stroke: color, strokeWidth: 1.5, strokeDasharray: "4 2", opacity: 0.9 }),
5226
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: r2 * 0.4, fill: color, opacity: 0.3, children: /* @__PURE__ */ jsx("animate", { attributeName: "opacity", values: "0.3;0.6;0.3", dur: "2s", repeatCount: "indefinite" }) })
5227
+ ] });
5228
+ case "singleton":
5229
+ return /* @__PURE__ */ jsx(
5230
+ "rect",
5231
+ {
5232
+ x: cx - r2 * 0.7,
5233
+ y: cy - r2 * 0.7,
5234
+ width: r2 * 1.4,
5235
+ height: r2 * 1.4,
5236
+ transform: `rotate(45 ${cx} ${cy})`,
5237
+ fill: color,
5238
+ fillOpacity: 0.15,
5239
+ stroke: color,
5240
+ strokeWidth: 1.5
5241
+ }
5242
+ );
5243
+ case "instance":
5244
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
5245
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: r2, fill: color, fillOpacity: 0.1, stroke: color, strokeWidth: 1, strokeDasharray: "2 2" }),
5246
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: r2 * 0.5, fill: color, fillOpacity: 0.2 })
5247
+ ] });
5248
+ case "persistent":
5249
+ default:
5250
+ return /* @__PURE__ */ jsx("circle", { cx, cy, r: r2, fill: color, fillOpacity: 0.15, stroke: color, strokeWidth: 2 });
5251
+ }
5252
+ }
5253
+ function FieldSpokes({ cx, cy, innerR, outerR, count, color }) {
5254
+ if (count === 0) return null;
5255
+ const spokes = Array.from({ length: count }, (_, i) => {
5256
+ const angle = Math.PI * 2 * i / count - Math.PI / 2;
5257
+ return /* @__PURE__ */ jsx(
5258
+ "line",
5259
+ {
5260
+ x1: cx + innerR * Math.cos(angle),
5261
+ y1: cy + innerR * Math.sin(angle),
5262
+ x2: cx + outerR * Math.cos(angle),
5263
+ y2: cy + outerR * Math.sin(angle),
5264
+ stroke: color,
5265
+ strokeWidth: 1,
5266
+ opacity: 0.5
5267
+ },
5268
+ i
5269
+ );
5270
+ });
5271
+ return /* @__PURE__ */ jsx(Fragment, { children: spokes });
5272
+ }
5273
+ function StateRings({ cx, cy, baseR, count, color, animated }) {
5274
+ if (count === 0) return null;
5275
+ const ringCount = Math.min(count, 5);
5276
+ const ringSpacing = baseR * 0.25;
5277
+ const rings = Array.from({ length: ringCount }, (_, i) => {
5278
+ const r2 = baseR + (i + 1) * ringSpacing;
5279
+ const opacity = 0.6 - i * 0.1;
5280
+ const width = i === 0 ? 1.5 : 1;
5281
+ return /* @__PURE__ */ jsx(
5282
+ "circle",
5283
+ {
5284
+ cx,
5285
+ cy,
5286
+ r: r2,
5287
+ fill: "none",
5288
+ stroke: color,
5289
+ strokeWidth: width,
5290
+ opacity,
5291
+ children: animated && /* @__PURE__ */ jsx(
5292
+ "animateTransform",
5293
+ {
5294
+ attributeName: "transform",
5295
+ type: "rotate",
5296
+ from: `0 ${cx} ${cy}`,
5297
+ to: `${i % 2 === 0 ? 360 : -360} ${cx} ${cy}`,
5298
+ dur: `${8 + i * 4}s`,
5299
+ repeatCount: "indefinite"
5300
+ }
5301
+ )
5302
+ },
5303
+ i
5304
+ );
5305
+ });
5306
+ return /* @__PURE__ */ jsx(Fragment, { children: rings });
5307
+ }
5308
+ function EffectMarkers({ cx, cy, r: r2, effectTypes, baseColor }) {
5309
+ if (effectTypes.length === 0) return null;
5310
+ const seen = /* @__PURE__ */ new Set();
5311
+ const categories = [];
5312
+ for (const t of effectTypes) {
5313
+ const cat = EFFECT_TYPE_TO_CATEGORY[t];
5314
+ if (!seen.has(cat)) {
5315
+ seen.add(cat);
5316
+ categories.push({ type: t, category: cat });
5317
+ }
5318
+ }
5319
+ return /* @__PURE__ */ jsx(Fragment, { children: categories.map(({ type, category }, i) => {
5320
+ const angle = Math.PI * 2 * i / categories.length - Math.PI / 2;
5321
+ const mx = cx + r2 * Math.cos(angle);
5322
+ const my = cy + r2 * Math.sin(angle);
5323
+ const markerColor = EFFECT_CATEGORY_COLORS[category].color;
5324
+ const s = r2 * 0.12;
5325
+ return /* @__PURE__ */ jsxs("g", { children: [
5326
+ /* @__PURE__ */ jsx("circle", { cx: mx, cy: my, r: s + 1, fill: markerColor, fillOpacity: 0.2 }),
5327
+ /* @__PURE__ */ jsx("circle", { cx: mx, cy: my, r: s * 0.6, fill: markerColor })
5328
+ ] }, type);
5329
+ }) });
5330
+ }
5331
+ function AtomGlyph({ cx, cy, radius, fieldCount, stateCount, persistence, effectTypes, color, animated, showLabels, name }) {
5332
+ const coreR = radius * 0.25;
5333
+ const spokeInner = coreR + 2;
5334
+ const spokeOuter = coreR + radius * 0.15;
5335
+ const ringBase = coreR + radius * 0.18;
5336
+ const markerR = ringBase + Math.min(stateCount, 5) * (radius * 0.25) * 0.25 + radius * 0.08;
5337
+ return /* @__PURE__ */ jsxs("g", { children: [
5338
+ /* @__PURE__ */ jsx(PersistenceCore, { cx, cy, r: coreR, persistence, color }),
5339
+ /* @__PURE__ */ jsx(FieldSpokes, { cx, cy, innerR: spokeInner, outerR: spokeOuter, count: fieldCount, color }),
5340
+ /* @__PURE__ */ jsx(StateRings, { cx, cy, baseR: ringBase, count: stateCount, color, animated }),
5341
+ /* @__PURE__ */ jsx(EffectMarkers, { cx, cy, r: markerR, effectTypes, baseColor: color }),
5342
+ showLabels && /* @__PURE__ */ jsx(
5343
+ "text",
5344
+ {
5345
+ x: cx,
5346
+ y: cy + radius + 12,
5347
+ textAnchor: "middle",
5348
+ fill: color,
5349
+ fontSize: radius * 0.14,
5350
+ fontFamily: "Inter, sans-serif",
5351
+ fontWeight: 500,
5352
+ opacity: 0.8,
5353
+ children: name
5354
+ }
5355
+ )
5356
+ ] });
5357
+ }
5358
+ function MoleculeGlyph({ cx, cy, radius, children, color, animated, showLabels, name }) {
5359
+ const count = children.length || 1;
5360
+ const childR = radius / (count <= 3 ? 2.8 : 3.5);
5361
+ const orbitR = radius * 0.5;
5362
+ return /* @__PURE__ */ jsxs("g", { children: [
5363
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: orbitR, fill: "none", stroke: color, strokeWidth: 0.8, strokeDasharray: "3 2", opacity: 0.3 }),
5364
+ children.map((child, i) => {
5365
+ const angle = Math.PI * 2 * i / count - Math.PI / 2;
5366
+ const childCx = cx + orbitR * Math.cos(angle);
5367
+ const childCy = cy + orbitR * Math.sin(angle);
5368
+ return /* @__PURE__ */ jsxs("g", { children: [
5369
+ /* @__PURE__ */ jsx("line", { x1: cx, y1: cy, x2: childCx, y2: childCy, stroke: color, strokeWidth: 0.5, opacity: 0.2 }),
5370
+ /* @__PURE__ */ jsx(
5371
+ AtomGlyph,
5372
+ {
5373
+ cx: childCx,
5374
+ cy: childCy,
5375
+ radius: childR,
5376
+ fieldCount: child.fieldCount ?? 3,
5377
+ stateCount: child.stateCount ?? 2,
5378
+ persistence: child.persistence ?? "persistent",
5379
+ effectTypes: child.effectTypes ?? ["render-ui"],
5380
+ color,
5381
+ animated,
5382
+ showLabels: false,
5383
+ name: child.name
5384
+ }
5385
+ )
5386
+ ] }, child.name);
5387
+ }),
5388
+ /* @__PURE__ */ jsx("circle", { cx, cy, r: radius * 0.04, fill: color, opacity: 0.5 }),
5389
+ showLabels && /* @__PURE__ */ jsx(
5390
+ "text",
5391
+ {
5392
+ x: cx,
5393
+ y: cy + radius + 12,
5394
+ textAnchor: "middle",
5395
+ fill: color,
5396
+ fontSize: radius * 0.12,
5397
+ fontFamily: "Inter, sans-serif",
5398
+ fontWeight: 500,
5399
+ opacity: 0.8,
5400
+ children: name
5401
+ }
5402
+ )
5403
+ ] });
5404
+ }
5405
+ function OrganismGlyph({ cx, cy, radius, children, connections, color, animated, showLabels, name }) {
5406
+ const count = children.length || 1;
5407
+ const childR = radius / (count <= 3 ? 3 : 4);
5408
+ const spreadX = radius * 0.6;
5409
+ const positions = children.map((_, i) => {
5410
+ const offset = (i - (count - 1) / 2) * (spreadX * 2 / Math.max(count - 1, 1));
5411
+ return { x: cx + offset, y: cy };
5412
+ });
5413
+ const nameToIdx = {};
5414
+ children.forEach((c, i) => {
5415
+ nameToIdx[c.name] = i;
5416
+ });
5417
+ return /* @__PURE__ */ jsxs("g", { children: [
5418
+ /* @__PURE__ */ jsx(
5419
+ "rect",
5420
+ {
5421
+ x: cx - radius,
5422
+ y: cy - radius * 0.7,
5423
+ width: radius * 2,
5424
+ height: radius * 1.4,
5425
+ rx: radius * 0.08,
5426
+ fill: color,
5427
+ fillOpacity: 0.03,
5428
+ stroke: color,
5429
+ strokeWidth: 0.8,
5430
+ strokeDasharray: "6 3",
5431
+ opacity: 0.4
5432
+ }
5433
+ ),
5434
+ connections.map((conn, i) => {
5435
+ const fromIdx = nameToIdx[conn.from];
5436
+ const toIdx = nameToIdx[conn.to];
5437
+ if (fromIdx == null || toIdx == null) return null;
5438
+ const from = positions[fromIdx];
5439
+ const to = positions[toIdx];
5440
+ return /* @__PURE__ */ jsxs("g", { children: [
5441
+ /* @__PURE__ */ jsx(
5442
+ "line",
5443
+ {
5444
+ x1: from.x + childR,
5445
+ y1: from.y,
5446
+ x2: to.x - childR,
5447
+ y2: to.y,
5448
+ stroke: color,
5449
+ strokeWidth: 1,
5450
+ opacity: 0.4,
5451
+ markerEnd: "none"
5452
+ }
5453
+ ),
5454
+ /* @__PURE__ */ jsx(
5455
+ "polygon",
5456
+ {
5457
+ points: `${to.x - childR - 4},${to.y - 3} ${to.x - childR},${to.y} ${to.x - childR - 4},${to.y + 3}`,
5458
+ fill: color,
5459
+ opacity: 0.5
5460
+ }
5461
+ ),
5462
+ showLabels && /* @__PURE__ */ jsx(
5463
+ "text",
5464
+ {
5465
+ x: (from.x + to.x) / 2,
5466
+ y: from.y - childR - 4,
5467
+ textAnchor: "middle",
5468
+ fill: color,
5469
+ fontSize: radius * 0.06,
5470
+ fontFamily: "Inter, sans-serif",
5471
+ opacity: 0.5,
5472
+ children: conn.event
5473
+ }
5474
+ )
5475
+ ] }, i);
5476
+ }),
5477
+ children.map((child, i) => {
5478
+ const pos = positions[i];
5479
+ return /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
5480
+ AtomGlyph,
5481
+ {
5482
+ cx: pos.x,
5483
+ cy: pos.y,
5484
+ radius: childR,
5485
+ fieldCount: child.fieldCount ?? 3,
5486
+ stateCount: child.stateCount ?? 2,
5487
+ persistence: child.persistence ?? "persistent",
5488
+ effectTypes: child.effectTypes ?? ["render-ui"],
5489
+ color,
5490
+ animated,
5491
+ showLabels,
5492
+ name: child.name
5493
+ }
5494
+ ) }, child.name);
5495
+ }),
5496
+ showLabels && /* @__PURE__ */ jsx(
5497
+ "text",
5498
+ {
5499
+ x: cx,
5500
+ y: cy + radius * 0.7 + 14,
5501
+ textAnchor: "middle",
5502
+ fill: color,
5503
+ fontSize: radius * 0.1,
5504
+ fontFamily: "Inter, sans-serif",
5505
+ fontWeight: 600,
5506
+ opacity: 0.8,
5507
+ children: name
5508
+ }
5509
+ )
5510
+ ] });
5511
+ }
5512
+ var AvlBehaviorGlyph = ({
5513
+ name,
5514
+ level = "atom",
5515
+ domain,
5516
+ color: colorOverride,
5517
+ fieldCount = 4,
5518
+ stateCount = 2,
5519
+ persistence = "persistent",
5520
+ effectTypes = [],
5521
+ children: childBehaviors,
5522
+ connections = [],
5523
+ size = "md",
5524
+ showLabels = false,
5525
+ animated = false,
5526
+ className,
5527
+ onClick
5528
+ }) => {
5529
+ const resolvedColor = colorOverride ?? (domain ? DOMAIN_COLORS[domain] ?? "#14b8a6" : "#14b8a6");
5530
+ const dim = SIZE_MAP[size];
5531
+ const radius = dim * 0.4;
5532
+ const cx = dim / 2;
5533
+ const cy = dim / 2;
5534
+ const vb = level === "organism" ? `0 0 ${dim * 1.5} ${dim}` : `0 0 ${dim} ${dim}`;
5535
+ const svgW = level === "organism" ? dim * 1.5 : dim;
5536
+ const glyphId = useMemo(() => `avl-bg-${Math.random().toString(36).slice(2, 8)}`, []);
5537
+ return /* @__PURE__ */ jsxs(
5538
+ "svg",
5539
+ {
5540
+ viewBox: vb,
5541
+ width: svgW,
5542
+ height: dim,
5543
+ xmlns: "http://www.w3.org/2000/svg",
5544
+ className: cn("inline-block", onClick && "cursor-pointer", className),
5545
+ onClick,
5546
+ role: onClick ? "button" : void 0,
5547
+ "aria-label": `${name} behavior glyph`,
5548
+ children: [
5549
+ /* @__PURE__ */ jsx("defs", { children: /* @__PURE__ */ jsxs("radialGradient", { id: `${glyphId}-bg`, cx: "50%", cy: "50%", r: "50%", children: [
5550
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: resolvedColor, stopOpacity: 0.06 }),
5551
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: resolvedColor, stopOpacity: 0 })
5552
+ ] }) }),
5553
+ /* @__PURE__ */ jsx("circle", { cx: level === "organism" ? dim * 0.75 : cx, cy, r: radius * 1.3, fill: `url(#${glyphId}-bg)` }),
5554
+ level === "atom" && /* @__PURE__ */ jsx(
5555
+ AtomGlyph,
5556
+ {
5557
+ cx,
5558
+ cy,
5559
+ radius,
5560
+ fieldCount,
5561
+ stateCount,
5562
+ persistence,
5563
+ effectTypes,
5564
+ color: resolvedColor,
5565
+ animated,
5566
+ showLabels,
5567
+ name
5568
+ }
5569
+ ),
5570
+ level === "molecule" && /* @__PURE__ */ jsx(
5571
+ MoleculeGlyph,
5572
+ {
5573
+ cx,
5574
+ cy,
5575
+ radius,
5576
+ children: childBehaviors ?? [],
5577
+ color: resolvedColor,
5578
+ animated,
5579
+ showLabels,
5580
+ name
5581
+ }
5582
+ ),
5583
+ level === "organism" && /* @__PURE__ */ jsx(
5584
+ OrganismGlyph,
5585
+ {
5586
+ cx: dim * 0.75,
5587
+ cy,
5588
+ radius: radius * 1.5,
5589
+ children: childBehaviors ?? [],
5590
+ connections,
5591
+ color: resolvedColor,
5592
+ animated,
5593
+ showLabels,
5594
+ name
5595
+ }
5596
+ )
5597
+ ]
5598
+ }
5599
+ );
5600
+ };
5601
+ AvlBehaviorGlyph.displayName = "AvlBehaviorGlyph";
5194
5602
 
5195
5603
  // components/organisms/avl/avl-schema-parser.ts
5196
5604
  function getEntity(orbital) {
@@ -6811,4 +7219,4 @@ var AvlCosmicZoom = ({
6811
7219
  };
6812
7220
  AvlCosmicZoom.displayName = "AvlCosmicZoom";
6813
7221
 
6814
- export { AVL_FIELD_TYPE_SHAPES, AVL_OPERATOR_COLORS, AvlApplication, AvlApplicationScene, AvlBinding, AvlBindingRef, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEffect, AvlEmitListen, AvlEntity, AvlEvent, AvlExprTree, AvlField, AvlFieldType, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlOrbitalScene, AvlOrbitalUnit, AvlPage, AvlPersistence, AvlSExpr, AvlSlotMap, AvlState, AvlStateMachine, AvlTrait, AvlTraitScene, AvlTransition, AvlTransitionScene, CONNECTION_COLORS, EFFECT_CATEGORY_COLORS, EFFECT_TYPE_TO_CATEGORY, STATE_COLORS, arcPath, curveControlPoint, getStateRole, gridPositions, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, radialPositions, ringPositions };
7222
+ export { AVL_FIELD_TYPE_SHAPES, AVL_OPERATOR_COLORS, AvlApplication, AvlApplicationScene, AvlBehaviorGlyph, AvlBinding, AvlBindingRef, AvlClickTarget, AvlClosedCircuit, AvlCosmicZoom, AvlEffect, AvlEmitListen, AvlEntity, AvlEvent, AvlExprTree, AvlField, AvlFieldType, AvlGuard, AvlLiteral, AvlOperator, AvlOrbital, AvlOrbitalScene, AvlOrbitalUnit, AvlPage, AvlPersistence, AvlSExpr, AvlSlotMap, AvlState, AvlStateMachine, AvlSwimLane, AvlTrait, AvlTraitScene, AvlTransition, AvlTransitionLane, AvlTransitionScene, CONNECTION_COLORS, DOMAIN_COLORS, EFFECT_CATEGORY_COLORS, EFFECT_TYPE_TO_CATEGORY, STATE_COLORS, arcPath, curveControlPoint, getStateRole, gridPositions, parseApplicationLevel, parseOrbitalLevel, parseTraitLevel, parseTransitionLevel, radialPositions, ringPositions };
@@ -6059,43 +6059,43 @@ function useQuerySingleton(query) {
6059
6059
  if (!query) {
6060
6060
  return null;
6061
6061
  }
6062
- const store = React91.useMemo(() => getOrCreateStore(query), [query]);
6062
+ const store2 = React91.useMemo(() => getOrCreateStore(query), [query]);
6063
6063
  React91.useMemo(() => {
6064
6064
  const listener = () => forceUpdate({});
6065
- store.listeners.add(listener);
6065
+ store2.listeners.add(listener);
6066
6066
  return () => {
6067
- store.listeners.delete(listener);
6067
+ store2.listeners.delete(listener);
6068
6068
  };
6069
- }, [store]);
6069
+ }, [store2]);
6070
6070
  const notifyListeners = React91.useCallback(() => {
6071
- store.listeners.forEach((listener) => listener());
6072
- }, [store]);
6071
+ store2.listeners.forEach((listener) => listener());
6072
+ }, [store2]);
6073
6073
  const setSearch = React91.useCallback((value) => {
6074
- store.search = value;
6074
+ store2.search = value;
6075
6075
  notifyListeners();
6076
- }, [store, notifyListeners]);
6076
+ }, [store2, notifyListeners]);
6077
6077
  const setFilter = React91.useCallback((key, value) => {
6078
- store.filters = { ...store.filters, [key]: value };
6078
+ store2.filters = { ...store2.filters, [key]: value };
6079
6079
  notifyListeners();
6080
- }, [store, notifyListeners]);
6080
+ }, [store2, notifyListeners]);
6081
6081
  const clearFilters = React91.useCallback(() => {
6082
- store.filters = {};
6083
- store.search = "";
6082
+ store2.filters = {};
6083
+ store2.search = "";
6084
6084
  notifyListeners();
6085
- }, [store, notifyListeners]);
6085
+ }, [store2, notifyListeners]);
6086
6086
  const setSort = React91.useCallback((field, direction) => {
6087
- store.sortField = field;
6088
- store.sortDirection = direction;
6087
+ store2.sortField = field;
6088
+ store2.sortDirection = direction;
6089
6089
  notifyListeners();
6090
- }, [store, notifyListeners]);
6090
+ }, [store2, notifyListeners]);
6091
6091
  return {
6092
- search: store.search,
6092
+ search: store2.search,
6093
6093
  setSearch,
6094
- filters: store.filters,
6094
+ filters: store2.filters,
6095
6095
  setFilter,
6096
6096
  clearFilters,
6097
- sortField: store.sortField,
6098
- sortDirection: store.sortDirection,
6097
+ sortField: store2.sortField,
6098
+ sortDirection: store2.sortDirection,
6099
6099
  setSort
6100
6100
  };
6101
6101
  }
@@ -27493,7 +27493,7 @@ function SequencerBoard({
27493
27493
  setPlayState("playing");
27494
27494
  setCurrentStep(0);
27495
27495
  let step = 0;
27496
- const advance = () => {
27496
+ const advance2 = () => {
27497
27497
  step++;
27498
27498
  if (step >= entity.maxSlots) {
27499
27499
  const playerSeq = slots.map((s) => s?.id);
@@ -27524,10 +27524,10 @@ function SequencerBoard({
27524
27524
  }
27525
27525
  } else {
27526
27526
  setCurrentStep(step);
27527
- timerRef.current = setTimeout(advance, stepDurationMs);
27527
+ timerRef.current = setTimeout(advance2, stepDurationMs);
27528
27528
  }
27529
27529
  };
27530
- timerRef.current = setTimeout(advance, stepDurationMs);
27530
+ timerRef.current = setTimeout(advance2, stepDurationMs);
27531
27531
  }, [canPlay, slots, entity.maxSlots, entity.solutions, stepDurationMs, playEvent, completeEvent, emit]);
27532
27532
  const machine = {
27533
27533
  name: entity.title,
@@ -29636,6 +29636,55 @@ function calculateDamage(attack, defense, isDefending = false, criticalChance =
29636
29636
  function generateCombatMessage(event) {
29637
29637
  return event.message;
29638
29638
  }
29639
+ var store = /* @__PURE__ */ new Map();
29640
+ var storeListeners = /* @__PURE__ */ new Set();
29641
+ var watchCallbacks = /* @__PURE__ */ new Map();
29642
+ function advance(entityType, data) {
29643
+ const prev = store.get(entityType);
29644
+ const oldData = prev?.data ?? [];
29645
+ store.set(entityType, { data, version: (prev?.version ?? 0) + 1 });
29646
+ for (const listener of storeListeners) {
29647
+ listener();
29648
+ }
29649
+ const cbs = watchCallbacks.get(entityType);
29650
+ if (cbs) {
29651
+ for (const cb of cbs) {
29652
+ try {
29653
+ cb(oldData, data);
29654
+ } catch {
29655
+ }
29656
+ }
29657
+ }
29658
+ }
29659
+ function getSnapshot2(entityType) {
29660
+ return store.get(entityType)?.data ?? [];
29661
+ }
29662
+ function getVersion(entityType) {
29663
+ return store.get(entityType)?.version ?? 0;
29664
+ }
29665
+ function subscribeToStore(listener) {
29666
+ storeListeners.add(listener);
29667
+ return () => {
29668
+ storeListeners.delete(listener);
29669
+ };
29670
+ }
29671
+ function useEntityRef(entityType) {
29672
+ const versionRef = React91.useRef(0);
29673
+ const dataRef = React91.useRef([]);
29674
+ const getSnapshotStable = React91__namespace.default.useCallback(() => {
29675
+ const currentVersion = getVersion(entityType);
29676
+ if (currentVersion !== versionRef.current) {
29677
+ versionRef.current = currentVersion;
29678
+ dataRef.current = getSnapshot2(entityType);
29679
+ }
29680
+ return dataRef.current;
29681
+ }, [entityType]);
29682
+ return React91.useSyncExternalStore(subscribeToStore, getSnapshotStable, () => []);
29683
+ }
29684
+ React91.createContext({
29685
+ advance,
29686
+ getSnapshot: getSnapshot2
29687
+ });
29639
29688
  var ClientEffectConfigContext = React91.createContext(null);
29640
29689
  ClientEffectConfigContext.Provider;
29641
29690
 
@@ -35036,6 +35085,9 @@ function SlotContentRenderer({
35036
35085
  content,
35037
35086
  onDismiss
35038
35087
  }) {
35088
+ const entityProp = content.props.entity;
35089
+ const entityType = typeof entityProp === "string" ? entityProp : "";
35090
+ const storeData = useEntityRef(entityType);
35039
35091
  const PatternComponent = getComponentForPattern(content.pattern);
35040
35092
  if (PatternComponent) {
35041
35093
  const childrenConfig = content.props.children;
@@ -35043,13 +35095,14 @@ function SlotContentRenderer({
35043
35095
  const renderedChildren = hasChildren ? renderPatternChildren(childrenConfig, onDismiss, content.id) : void 0;
35044
35096
  const { children: _childrenConfig, ...restProps } = content.props;
35045
35097
  const renderedProps = renderPatternProps(restProps, onDismiss);
35098
+ const finalProps = entityType ? { ...renderedProps, entity: storeData } : renderedProps;
35046
35099
  return /* @__PURE__ */ jsxRuntime.jsx(
35047
35100
  Box,
35048
35101
  {
35049
35102
  className: "slot-content",
35050
35103
  "data-pattern": content.pattern,
35051
35104
  "data-id": content.id,
35052
- children: /* @__PURE__ */ jsxRuntime.jsx(PatternComponent, { ...renderedProps, children: renderedChildren })
35105
+ children: /* @__PURE__ */ jsxRuntime.jsx(PatternComponent, { ...finalProps, children: renderedChildren })
35053
35106
  }
35054
35107
  );
35055
35108
  }
@@ -37604,13 +37657,13 @@ function clearEntities() {
37604
37657
  entities = /* @__PURE__ */ new Map();
37605
37658
  notify();
37606
37659
  }
37607
- function getSnapshot2() {
37660
+ function getSnapshot3() {
37608
37661
  return entities;
37609
37662
  }
37610
37663
 
37611
37664
  // hooks/useEntities.ts
37612
37665
  function useEntities() {
37613
- const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2);
37666
+ const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
37614
37667
  return {
37615
37668
  entities: entities2,
37616
37669
  getEntity,
@@ -37625,15 +37678,15 @@ function useEntities() {
37625
37678
  };
37626
37679
  }
37627
37680
  function useEntity2(id) {
37628
- const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2);
37681
+ const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
37629
37682
  return entities2.get(id);
37630
37683
  }
37631
37684
  function useEntitiesByType(type) {
37632
- const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2);
37685
+ const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
37633
37686
  return [...entities2.values()].filter((e) => e.type === type);
37634
37687
  }
37635
37688
  function useSingletonEntity(type) {
37636
- const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2);
37689
+ const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
37637
37690
  return [...entities2.values()].find((e) => e.type === type);
37638
37691
  }
37639
37692
  function usePlayer() {