@almadar/ui 5.9.7 → 5.9.9
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 +119 -40
- package/dist/avl/index.js +119 -40
- package/dist/components/index.cjs +24 -3
- package/dist/components/index.js +24 -3
- package/dist/components/molecules/game/GameCanvas2D.d.ts +5 -1
- package/dist/providers/index.cjs +24 -3
- package/dist/providers/index.js +24 -3
- package/dist/runtime/embedded-traits.d.ts +8 -1
- package/dist/runtime/index.cjs +119 -40
- package/dist/runtime/index.js +119 -40
- package/dist/runtime/orbitalsByTrait.d.ts +34 -0
- package/package.json +1 -1
package/dist/avl/index.cjs
CHANGED
|
@@ -14619,7 +14619,7 @@ var init_MapView = __esm({
|
|
|
14619
14619
|
shadowSize: [41, 41]
|
|
14620
14620
|
});
|
|
14621
14621
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
14622
|
-
const { useEffect: useEffect89, useRef: useRef88, useCallback:
|
|
14622
|
+
const { useEffect: useEffect89, useRef: useRef88, useCallback: useCallback130, useState: useState124 } = React98__namespace.default;
|
|
14623
14623
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
14624
14624
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
14625
14625
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -14665,7 +14665,7 @@ var init_MapView = __esm({
|
|
|
14665
14665
|
}) {
|
|
14666
14666
|
const eventBus = useEventBus3();
|
|
14667
14667
|
const [clickedPosition, setClickedPosition] = useState124(null);
|
|
14668
|
-
const handleMapClick =
|
|
14668
|
+
const handleMapClick = useCallback130((lat, lng) => {
|
|
14669
14669
|
if (showClickedPin) {
|
|
14670
14670
|
setClickedPosition({ lat, lng });
|
|
14671
14671
|
}
|
|
@@ -14674,7 +14674,7 @@ var init_MapView = __esm({
|
|
|
14674
14674
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
14675
14675
|
}
|
|
14676
14676
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
14677
|
-
const handleMarkerClick =
|
|
14677
|
+
const handleMarkerClick = useCallback130((marker) => {
|
|
14678
14678
|
onMarkerClick?.(marker);
|
|
14679
14679
|
if (markerClickEvent) {
|
|
14680
14680
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -30399,12 +30399,15 @@ function GameCanvas2D({
|
|
|
30399
30399
|
tickEvent,
|
|
30400
30400
|
drawEvent,
|
|
30401
30401
|
fps = 60,
|
|
30402
|
+
backgroundImage,
|
|
30403
|
+
assetBaseUrl = "",
|
|
30402
30404
|
className
|
|
30403
30405
|
}) {
|
|
30404
30406
|
const canvasRef = React98__namespace.useRef(null);
|
|
30405
30407
|
const rafRef = React98__namespace.useRef(0);
|
|
30406
30408
|
const frameRef = React98__namespace.useRef(0);
|
|
30407
30409
|
const lastTimeRef = React98__namespace.useRef(0);
|
|
30410
|
+
const imageCache = React98__namespace.useRef(/* @__PURE__ */ new Map());
|
|
30408
30411
|
const emit = useEmitEvent();
|
|
30409
30412
|
const onDrawRef = React98__namespace.useRef(onDraw);
|
|
30410
30413
|
onDrawRef.current = onDraw;
|
|
@@ -30416,6 +30419,18 @@ function GameCanvas2D({
|
|
|
30416
30419
|
drawEventRef.current = drawEvent;
|
|
30417
30420
|
const emitRef = React98__namespace.useRef(emit);
|
|
30418
30421
|
emitRef.current = emit;
|
|
30422
|
+
const loadImage = React98__namespace.useCallback((url) => {
|
|
30423
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
30424
|
+
const cached = imageCache.current.get(fullUrl);
|
|
30425
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
30426
|
+
if (!cached) {
|
|
30427
|
+
const img = new Image();
|
|
30428
|
+
img.crossOrigin = "anonymous";
|
|
30429
|
+
img.src = fullUrl;
|
|
30430
|
+
imageCache.current.set(fullUrl, img);
|
|
30431
|
+
}
|
|
30432
|
+
return null;
|
|
30433
|
+
}, [assetBaseUrl]);
|
|
30419
30434
|
React98__namespace.useEffect(() => {
|
|
30420
30435
|
const canvas = canvasRef.current;
|
|
30421
30436
|
if (!canvas) return;
|
|
@@ -30437,6 +30452,12 @@ function GameCanvas2D({
|
|
|
30437
30452
|
if (tickEventRef.current) {
|
|
30438
30453
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
30439
30454
|
}
|
|
30455
|
+
if (backgroundImage) {
|
|
30456
|
+
const bgImg = loadImage(backgroundImage);
|
|
30457
|
+
if (bgImg) {
|
|
30458
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
30459
|
+
}
|
|
30460
|
+
}
|
|
30440
30461
|
onDrawRef.current?.(ctx, frame);
|
|
30441
30462
|
if (drawEventRef.current) {
|
|
30442
30463
|
emitRef.current(drawEventRef.current, { frame });
|
|
@@ -60012,6 +60033,16 @@ function collectTraitRefsFromEffects(effects, into) {
|
|
|
60012
60033
|
}
|
|
60013
60034
|
}
|
|
60014
60035
|
}
|
|
60036
|
+
function collectTraitRefsFromResolvedTrait(trait) {
|
|
60037
|
+
const out = /* @__PURE__ */ new Set();
|
|
60038
|
+
for (const transition of trait.transitions ?? []) {
|
|
60039
|
+
collectTraitRefsFromEffects(transition.effects, out);
|
|
60040
|
+
}
|
|
60041
|
+
for (const tick of trait.ticks ?? []) {
|
|
60042
|
+
collectTraitRefsFromEffects(tick.effects, out);
|
|
60043
|
+
}
|
|
60044
|
+
return out;
|
|
60045
|
+
}
|
|
60015
60046
|
function collectEmbeddedTraits(schema) {
|
|
60016
60047
|
const out = /* @__PURE__ */ new Set();
|
|
60017
60048
|
if (!schema?.orbitals) return out;
|
|
@@ -60902,6 +60933,40 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
60902
60933
|
};
|
|
60903
60934
|
}
|
|
60904
60935
|
|
|
60936
|
+
// runtime/orbitalsByTrait.ts
|
|
60937
|
+
function buildOrbitalsByTrait(schema, resolvedPages = []) {
|
|
60938
|
+
const map = {};
|
|
60939
|
+
if (!schema?.orbitals) return map;
|
|
60940
|
+
const pagePathToOrbital = {};
|
|
60941
|
+
for (const orb of schema.orbitals) {
|
|
60942
|
+
for (const traitRef of orb.traits ?? []) {
|
|
60943
|
+
let traitName;
|
|
60944
|
+
if (typeof traitRef === "string") {
|
|
60945
|
+
const parts = traitRef.split(".");
|
|
60946
|
+
traitName = parts[parts.length - 1];
|
|
60947
|
+
} else if (typeof traitRef.ref === "string") {
|
|
60948
|
+
const parts = traitRef.ref.split(".");
|
|
60949
|
+
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
60950
|
+
} else if (typeof traitRef.name === "string") {
|
|
60951
|
+
traitName = traitRef.name;
|
|
60952
|
+
}
|
|
60953
|
+
if (traitName) map[traitName] = orb.name;
|
|
60954
|
+
}
|
|
60955
|
+
for (const pg of orb.pages ?? []) {
|
|
60956
|
+
const path = typeof pg === "string" ? pg : pg?.path;
|
|
60957
|
+
if (path) pagePathToOrbital[path] = orb.name;
|
|
60958
|
+
}
|
|
60959
|
+
}
|
|
60960
|
+
for (const page of resolvedPages) {
|
|
60961
|
+
const orbital = page.path ? pagePathToOrbital[page.path] : void 0;
|
|
60962
|
+
if (!orbital) continue;
|
|
60963
|
+
for (const traitName of page.traitNames) {
|
|
60964
|
+
if (traitName && !(traitName in map)) map[traitName] = orbital;
|
|
60965
|
+
}
|
|
60966
|
+
}
|
|
60967
|
+
return map;
|
|
60968
|
+
}
|
|
60969
|
+
|
|
60905
60970
|
// runtime/OrbPreview.tsx
|
|
60906
60971
|
init_EntitySchemaContext();
|
|
60907
60972
|
|
|
@@ -61637,50 +61702,64 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
61637
61702
|
return null;
|
|
61638
61703
|
}
|
|
61639
61704
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
61640
|
-
const { traits: traits2, allEntities, ir } = useResolvedSchema(schema, pageName);
|
|
61705
|
+
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
61641
61706
|
const allPageTraits = React98.useMemo(() => {
|
|
61642
|
-
|
|
61643
|
-
if (
|
|
61644
|
-
|
|
61645
|
-
if (!
|
|
61646
|
-
|
|
61647
|
-
|
|
61648
|
-
|
|
61649
|
-
|
|
61650
|
-
|
|
61651
|
-
|
|
61652
|
-
firstPageTraits
|
|
61653
|
-
|
|
61654
|
-
|
|
61655
|
-
|
|
61656
|
-
|
|
61707
|
+
let base;
|
|
61708
|
+
if (pageName && traits2.length > 0) {
|
|
61709
|
+
base = traits2;
|
|
61710
|
+
} else if (!ir?.pages || ir.pages.size <= 1) {
|
|
61711
|
+
base = traits2;
|
|
61712
|
+
} else {
|
|
61713
|
+
const firstPage = ir.pages.values().next().value;
|
|
61714
|
+
if (!firstPage) {
|
|
61715
|
+
base = traits2;
|
|
61716
|
+
} else {
|
|
61717
|
+
const firstPageTraits = [];
|
|
61718
|
+
const seen = /* @__PURE__ */ new Set();
|
|
61719
|
+
for (const binding of firstPage.traits) {
|
|
61720
|
+
const name = binding.trait.name;
|
|
61721
|
+
if (name && !seen.has(name)) {
|
|
61722
|
+
seen.add(name);
|
|
61723
|
+
firstPageTraits.push(binding);
|
|
61724
|
+
}
|
|
61725
|
+
}
|
|
61726
|
+
base = firstPageTraits.length > 0 ? firstPageTraits : traits2;
|
|
61727
|
+
}
|
|
61728
|
+
}
|
|
61729
|
+
const byName = new Set(base.map((b) => b.trait.name));
|
|
61730
|
+
const extra = [];
|
|
61731
|
+
const queue = [...base];
|
|
61732
|
+
while (queue.length > 0) {
|
|
61733
|
+
const binding = queue.shift();
|
|
61734
|
+
if (!binding) continue;
|
|
61735
|
+
for (const refName of collectTraitRefsFromResolvedTrait(binding.trait)) {
|
|
61736
|
+
if (byName.has(refName)) continue;
|
|
61737
|
+
const rt = allTraits.get(refName);
|
|
61738
|
+
if (!rt) continue;
|
|
61739
|
+
byName.add(refName);
|
|
61740
|
+
const sibling = { trait: rt, linkedEntity: rt.linkedEntity };
|
|
61741
|
+
extra.push(sibling);
|
|
61742
|
+
queue.push(sibling);
|
|
61743
|
+
}
|
|
61744
|
+
}
|
|
61745
|
+
return extra.length > 0 ? [...base, ...extra] : base;
|
|
61746
|
+
}, [ir, traits2, pageName, allTraits]);
|
|
61657
61747
|
React98.useMemo(() => {
|
|
61658
61748
|
const parsed = schema;
|
|
61659
61749
|
const orbitals = parsed?.orbitals;
|
|
61660
61750
|
if (!orbitals) return [];
|
|
61661
61751
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
61662
61752
|
}, [schema]);
|
|
61663
|
-
const orbitalsByTrait = React98.useMemo(
|
|
61664
|
-
|
|
61665
|
-
|
|
61666
|
-
|
|
61667
|
-
|
|
61668
|
-
|
|
61669
|
-
|
|
61670
|
-
|
|
61671
|
-
|
|
61672
|
-
|
|
61673
|
-
} else if ("ref" in traitRef && typeof traitRef.ref === "string") {
|
|
61674
|
-
const parts = traitRef.ref.split(".");
|
|
61675
|
-
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
61676
|
-
} else if ("name" in traitRef && typeof traitRef.name === "string") {
|
|
61677
|
-
traitName = traitRef.name;
|
|
61678
|
-
}
|
|
61679
|
-
if (traitName) map[traitName] = orb.name;
|
|
61680
|
-
}
|
|
61681
|
-
}
|
|
61682
|
-
return map;
|
|
61683
|
-
}, [schema]);
|
|
61753
|
+
const orbitalsByTrait = React98.useMemo(
|
|
61754
|
+
() => buildOrbitalsByTrait(
|
|
61755
|
+
schema,
|
|
61756
|
+
ir ? Array.from(ir.pages.values()).map((p2) => ({
|
|
61757
|
+
path: p2.path,
|
|
61758
|
+
traitNames: p2.traits.map((b) => b.trait.name)
|
|
61759
|
+
})) : []
|
|
61760
|
+
),
|
|
61761
|
+
[schema, ir]
|
|
61762
|
+
);
|
|
61684
61763
|
const traitLinkedEntitiesMap = React98.useMemo(() => {
|
|
61685
61764
|
const map = /* @__PURE__ */ new Map();
|
|
61686
61765
|
if (ir) {
|
package/dist/avl/index.js
CHANGED
|
@@ -14570,7 +14570,7 @@ var init_MapView = __esm({
|
|
|
14570
14570
|
shadowSize: [41, 41]
|
|
14571
14571
|
});
|
|
14572
14572
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
14573
|
-
const { useEffect: useEffect89, useRef: useRef88, useCallback:
|
|
14573
|
+
const { useEffect: useEffect89, useRef: useRef88, useCallback: useCallback130, useState: useState124 } = React98__default;
|
|
14574
14574
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
14575
14575
|
const { useEventBus: useEventBus3 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
14576
14576
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -14616,7 +14616,7 @@ var init_MapView = __esm({
|
|
|
14616
14616
|
}) {
|
|
14617
14617
|
const eventBus = useEventBus3();
|
|
14618
14618
|
const [clickedPosition, setClickedPosition] = useState124(null);
|
|
14619
|
-
const handleMapClick =
|
|
14619
|
+
const handleMapClick = useCallback130((lat, lng) => {
|
|
14620
14620
|
if (showClickedPin) {
|
|
14621
14621
|
setClickedPosition({ lat, lng });
|
|
14622
14622
|
}
|
|
@@ -14625,7 +14625,7 @@ var init_MapView = __esm({
|
|
|
14625
14625
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
14626
14626
|
}
|
|
14627
14627
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
14628
|
-
const handleMarkerClick =
|
|
14628
|
+
const handleMarkerClick = useCallback130((marker) => {
|
|
14629
14629
|
onMarkerClick?.(marker);
|
|
14630
14630
|
if (markerClickEvent) {
|
|
14631
14631
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -30350,12 +30350,15 @@ function GameCanvas2D({
|
|
|
30350
30350
|
tickEvent,
|
|
30351
30351
|
drawEvent,
|
|
30352
30352
|
fps = 60,
|
|
30353
|
+
backgroundImage,
|
|
30354
|
+
assetBaseUrl = "",
|
|
30353
30355
|
className
|
|
30354
30356
|
}) {
|
|
30355
30357
|
const canvasRef = React98.useRef(null);
|
|
30356
30358
|
const rafRef = React98.useRef(0);
|
|
30357
30359
|
const frameRef = React98.useRef(0);
|
|
30358
30360
|
const lastTimeRef = React98.useRef(0);
|
|
30361
|
+
const imageCache = React98.useRef(/* @__PURE__ */ new Map());
|
|
30359
30362
|
const emit = useEmitEvent();
|
|
30360
30363
|
const onDrawRef = React98.useRef(onDraw);
|
|
30361
30364
|
onDrawRef.current = onDraw;
|
|
@@ -30367,6 +30370,18 @@ function GameCanvas2D({
|
|
|
30367
30370
|
drawEventRef.current = drawEvent;
|
|
30368
30371
|
const emitRef = React98.useRef(emit);
|
|
30369
30372
|
emitRef.current = emit;
|
|
30373
|
+
const loadImage = React98.useCallback((url) => {
|
|
30374
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
30375
|
+
const cached = imageCache.current.get(fullUrl);
|
|
30376
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
30377
|
+
if (!cached) {
|
|
30378
|
+
const img = new Image();
|
|
30379
|
+
img.crossOrigin = "anonymous";
|
|
30380
|
+
img.src = fullUrl;
|
|
30381
|
+
imageCache.current.set(fullUrl, img);
|
|
30382
|
+
}
|
|
30383
|
+
return null;
|
|
30384
|
+
}, [assetBaseUrl]);
|
|
30370
30385
|
React98.useEffect(() => {
|
|
30371
30386
|
const canvas = canvasRef.current;
|
|
30372
30387
|
if (!canvas) return;
|
|
@@ -30388,6 +30403,12 @@ function GameCanvas2D({
|
|
|
30388
30403
|
if (tickEventRef.current) {
|
|
30389
30404
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
30390
30405
|
}
|
|
30406
|
+
if (backgroundImage) {
|
|
30407
|
+
const bgImg = loadImage(backgroundImage);
|
|
30408
|
+
if (bgImg) {
|
|
30409
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
30410
|
+
}
|
|
30411
|
+
}
|
|
30391
30412
|
onDrawRef.current?.(ctx, frame);
|
|
30392
30413
|
if (drawEventRef.current) {
|
|
30393
30414
|
emitRef.current(drawEventRef.current, { frame });
|
|
@@ -59963,6 +59984,16 @@ function collectTraitRefsFromEffects(effects, into) {
|
|
|
59963
59984
|
}
|
|
59964
59985
|
}
|
|
59965
59986
|
}
|
|
59987
|
+
function collectTraitRefsFromResolvedTrait(trait) {
|
|
59988
|
+
const out = /* @__PURE__ */ new Set();
|
|
59989
|
+
for (const transition of trait.transitions ?? []) {
|
|
59990
|
+
collectTraitRefsFromEffects(transition.effects, out);
|
|
59991
|
+
}
|
|
59992
|
+
for (const tick of trait.ticks ?? []) {
|
|
59993
|
+
collectTraitRefsFromEffects(tick.effects, out);
|
|
59994
|
+
}
|
|
59995
|
+
return out;
|
|
59996
|
+
}
|
|
59966
59997
|
function collectEmbeddedTraits(schema) {
|
|
59967
59998
|
const out = /* @__PURE__ */ new Set();
|
|
59968
59999
|
if (!schema?.orbitals) return out;
|
|
@@ -60853,6 +60884,40 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
60853
60884
|
};
|
|
60854
60885
|
}
|
|
60855
60886
|
|
|
60887
|
+
// runtime/orbitalsByTrait.ts
|
|
60888
|
+
function buildOrbitalsByTrait(schema, resolvedPages = []) {
|
|
60889
|
+
const map = {};
|
|
60890
|
+
if (!schema?.orbitals) return map;
|
|
60891
|
+
const pagePathToOrbital = {};
|
|
60892
|
+
for (const orb of schema.orbitals) {
|
|
60893
|
+
for (const traitRef of orb.traits ?? []) {
|
|
60894
|
+
let traitName;
|
|
60895
|
+
if (typeof traitRef === "string") {
|
|
60896
|
+
const parts = traitRef.split(".");
|
|
60897
|
+
traitName = parts[parts.length - 1];
|
|
60898
|
+
} else if (typeof traitRef.ref === "string") {
|
|
60899
|
+
const parts = traitRef.ref.split(".");
|
|
60900
|
+
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
60901
|
+
} else if (typeof traitRef.name === "string") {
|
|
60902
|
+
traitName = traitRef.name;
|
|
60903
|
+
}
|
|
60904
|
+
if (traitName) map[traitName] = orb.name;
|
|
60905
|
+
}
|
|
60906
|
+
for (const pg of orb.pages ?? []) {
|
|
60907
|
+
const path = typeof pg === "string" ? pg : pg?.path;
|
|
60908
|
+
if (path) pagePathToOrbital[path] = orb.name;
|
|
60909
|
+
}
|
|
60910
|
+
}
|
|
60911
|
+
for (const page of resolvedPages) {
|
|
60912
|
+
const orbital = page.path ? pagePathToOrbital[page.path] : void 0;
|
|
60913
|
+
if (!orbital) continue;
|
|
60914
|
+
for (const traitName of page.traitNames) {
|
|
60915
|
+
if (traitName && !(traitName in map)) map[traitName] = orbital;
|
|
60916
|
+
}
|
|
60917
|
+
}
|
|
60918
|
+
return map;
|
|
60919
|
+
}
|
|
60920
|
+
|
|
60856
60921
|
// runtime/OrbPreview.tsx
|
|
60857
60922
|
init_EntitySchemaContext();
|
|
60858
60923
|
|
|
@@ -61588,50 +61653,64 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
61588
61653
|
return null;
|
|
61589
61654
|
}
|
|
61590
61655
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
61591
|
-
const { traits: traits2, allEntities, ir } = useResolvedSchema(schema, pageName);
|
|
61656
|
+
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
61592
61657
|
const allPageTraits = useMemo(() => {
|
|
61593
|
-
|
|
61594
|
-
if (
|
|
61595
|
-
|
|
61596
|
-
if (!
|
|
61597
|
-
|
|
61598
|
-
|
|
61599
|
-
|
|
61600
|
-
|
|
61601
|
-
|
|
61602
|
-
|
|
61603
|
-
firstPageTraits
|
|
61604
|
-
|
|
61605
|
-
|
|
61606
|
-
|
|
61607
|
-
|
|
61658
|
+
let base;
|
|
61659
|
+
if (pageName && traits2.length > 0) {
|
|
61660
|
+
base = traits2;
|
|
61661
|
+
} else if (!ir?.pages || ir.pages.size <= 1) {
|
|
61662
|
+
base = traits2;
|
|
61663
|
+
} else {
|
|
61664
|
+
const firstPage = ir.pages.values().next().value;
|
|
61665
|
+
if (!firstPage) {
|
|
61666
|
+
base = traits2;
|
|
61667
|
+
} else {
|
|
61668
|
+
const firstPageTraits = [];
|
|
61669
|
+
const seen = /* @__PURE__ */ new Set();
|
|
61670
|
+
for (const binding of firstPage.traits) {
|
|
61671
|
+
const name = binding.trait.name;
|
|
61672
|
+
if (name && !seen.has(name)) {
|
|
61673
|
+
seen.add(name);
|
|
61674
|
+
firstPageTraits.push(binding);
|
|
61675
|
+
}
|
|
61676
|
+
}
|
|
61677
|
+
base = firstPageTraits.length > 0 ? firstPageTraits : traits2;
|
|
61678
|
+
}
|
|
61679
|
+
}
|
|
61680
|
+
const byName = new Set(base.map((b) => b.trait.name));
|
|
61681
|
+
const extra = [];
|
|
61682
|
+
const queue = [...base];
|
|
61683
|
+
while (queue.length > 0) {
|
|
61684
|
+
const binding = queue.shift();
|
|
61685
|
+
if (!binding) continue;
|
|
61686
|
+
for (const refName of collectTraitRefsFromResolvedTrait(binding.trait)) {
|
|
61687
|
+
if (byName.has(refName)) continue;
|
|
61688
|
+
const rt = allTraits.get(refName);
|
|
61689
|
+
if (!rt) continue;
|
|
61690
|
+
byName.add(refName);
|
|
61691
|
+
const sibling = { trait: rt, linkedEntity: rt.linkedEntity };
|
|
61692
|
+
extra.push(sibling);
|
|
61693
|
+
queue.push(sibling);
|
|
61694
|
+
}
|
|
61695
|
+
}
|
|
61696
|
+
return extra.length > 0 ? [...base, ...extra] : base;
|
|
61697
|
+
}, [ir, traits2, pageName, allTraits]);
|
|
61608
61698
|
useMemo(() => {
|
|
61609
61699
|
const parsed = schema;
|
|
61610
61700
|
const orbitals = parsed?.orbitals;
|
|
61611
61701
|
if (!orbitals) return [];
|
|
61612
61702
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
61613
61703
|
}, [schema]);
|
|
61614
|
-
const orbitalsByTrait = useMemo(
|
|
61615
|
-
|
|
61616
|
-
|
|
61617
|
-
|
|
61618
|
-
|
|
61619
|
-
|
|
61620
|
-
|
|
61621
|
-
|
|
61622
|
-
|
|
61623
|
-
|
|
61624
|
-
} else if ("ref" in traitRef && typeof traitRef.ref === "string") {
|
|
61625
|
-
const parts = traitRef.ref.split(".");
|
|
61626
|
-
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
61627
|
-
} else if ("name" in traitRef && typeof traitRef.name === "string") {
|
|
61628
|
-
traitName = traitRef.name;
|
|
61629
|
-
}
|
|
61630
|
-
if (traitName) map[traitName] = orb.name;
|
|
61631
|
-
}
|
|
61632
|
-
}
|
|
61633
|
-
return map;
|
|
61634
|
-
}, [schema]);
|
|
61704
|
+
const orbitalsByTrait = useMemo(
|
|
61705
|
+
() => buildOrbitalsByTrait(
|
|
61706
|
+
schema,
|
|
61707
|
+
ir ? Array.from(ir.pages.values()).map((p2) => ({
|
|
61708
|
+
path: p2.path,
|
|
61709
|
+
traitNames: p2.traits.map((b) => b.trait.name)
|
|
61710
|
+
})) : []
|
|
61711
|
+
),
|
|
61712
|
+
[schema, ir]
|
|
61713
|
+
);
|
|
61635
61714
|
const traitLinkedEntitiesMap = useMemo(() => {
|
|
61636
61715
|
const map = /* @__PURE__ */ new Map();
|
|
61637
61716
|
if (ir) {
|
|
@@ -8676,7 +8676,7 @@ var init_MapView = __esm({
|
|
|
8676
8676
|
shadowSize: [41, 41]
|
|
8677
8677
|
});
|
|
8678
8678
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
8679
|
-
const { useEffect: useEffect72, useRef: useRef66, useCallback:
|
|
8679
|
+
const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState110 } = React80__namespace.default;
|
|
8680
8680
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
8681
8681
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
8682
8682
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -8722,7 +8722,7 @@ var init_MapView = __esm({
|
|
|
8722
8722
|
}) {
|
|
8723
8723
|
const eventBus = useEventBus2();
|
|
8724
8724
|
const [clickedPosition, setClickedPosition] = useState110(null);
|
|
8725
|
-
const handleMapClick =
|
|
8725
|
+
const handleMapClick = useCallback128((lat, lng) => {
|
|
8726
8726
|
if (showClickedPin) {
|
|
8727
8727
|
setClickedPosition({ lat, lng });
|
|
8728
8728
|
}
|
|
@@ -8731,7 +8731,7 @@ var init_MapView = __esm({
|
|
|
8731
8731
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
8732
8732
|
}
|
|
8733
8733
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
8734
|
-
const handleMarkerClick =
|
|
8734
|
+
const handleMarkerClick = useCallback128((marker) => {
|
|
8735
8735
|
onMarkerClick?.(marker);
|
|
8736
8736
|
if (markerClickEvent) {
|
|
8737
8737
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -25784,12 +25784,15 @@ function GameCanvas2D({
|
|
|
25784
25784
|
tickEvent,
|
|
25785
25785
|
drawEvent,
|
|
25786
25786
|
fps = 60,
|
|
25787
|
+
backgroundImage,
|
|
25788
|
+
assetBaseUrl = "",
|
|
25787
25789
|
className
|
|
25788
25790
|
}) {
|
|
25789
25791
|
const canvasRef = React80__namespace.useRef(null);
|
|
25790
25792
|
const rafRef = React80__namespace.useRef(0);
|
|
25791
25793
|
const frameRef = React80__namespace.useRef(0);
|
|
25792
25794
|
const lastTimeRef = React80__namespace.useRef(0);
|
|
25795
|
+
const imageCache = React80__namespace.useRef(/* @__PURE__ */ new Map());
|
|
25793
25796
|
const emit = useEmitEvent();
|
|
25794
25797
|
const onDrawRef = React80__namespace.useRef(onDraw);
|
|
25795
25798
|
onDrawRef.current = onDraw;
|
|
@@ -25801,6 +25804,18 @@ function GameCanvas2D({
|
|
|
25801
25804
|
drawEventRef.current = drawEvent;
|
|
25802
25805
|
const emitRef = React80__namespace.useRef(emit);
|
|
25803
25806
|
emitRef.current = emit;
|
|
25807
|
+
const loadImage = React80__namespace.useCallback((url) => {
|
|
25808
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
25809
|
+
const cached = imageCache.current.get(fullUrl);
|
|
25810
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
25811
|
+
if (!cached) {
|
|
25812
|
+
const img = new Image();
|
|
25813
|
+
img.crossOrigin = "anonymous";
|
|
25814
|
+
img.src = fullUrl;
|
|
25815
|
+
imageCache.current.set(fullUrl, img);
|
|
25816
|
+
}
|
|
25817
|
+
return null;
|
|
25818
|
+
}, [assetBaseUrl]);
|
|
25804
25819
|
React80__namespace.useEffect(() => {
|
|
25805
25820
|
const canvas = canvasRef.current;
|
|
25806
25821
|
if (!canvas) return;
|
|
@@ -25822,6 +25837,12 @@ function GameCanvas2D({
|
|
|
25822
25837
|
if (tickEventRef.current) {
|
|
25823
25838
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
25824
25839
|
}
|
|
25840
|
+
if (backgroundImage) {
|
|
25841
|
+
const bgImg = loadImage(backgroundImage);
|
|
25842
|
+
if (bgImg) {
|
|
25843
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
25844
|
+
}
|
|
25845
|
+
}
|
|
25825
25846
|
onDrawRef.current?.(ctx, frame);
|
|
25826
25847
|
if (drawEventRef.current) {
|
|
25827
25848
|
emitRef.current(drawEventRef.current, { frame });
|
package/dist/components/index.js
CHANGED
|
@@ -8627,7 +8627,7 @@ var init_MapView = __esm({
|
|
|
8627
8627
|
shadowSize: [41, 41]
|
|
8628
8628
|
});
|
|
8629
8629
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
8630
|
-
const { useEffect: useEffect72, useRef: useRef66, useCallback:
|
|
8630
|
+
const { useEffect: useEffect72, useRef: useRef66, useCallback: useCallback128, useState: useState110 } = React80__default;
|
|
8631
8631
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
8632
8632
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
8633
8633
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -8673,7 +8673,7 @@ var init_MapView = __esm({
|
|
|
8673
8673
|
}) {
|
|
8674
8674
|
const eventBus = useEventBus2();
|
|
8675
8675
|
const [clickedPosition, setClickedPosition] = useState110(null);
|
|
8676
|
-
const handleMapClick =
|
|
8676
|
+
const handleMapClick = useCallback128((lat, lng) => {
|
|
8677
8677
|
if (showClickedPin) {
|
|
8678
8678
|
setClickedPosition({ lat, lng });
|
|
8679
8679
|
}
|
|
@@ -8682,7 +8682,7 @@ var init_MapView = __esm({
|
|
|
8682
8682
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
8683
8683
|
}
|
|
8684
8684
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
8685
|
-
const handleMarkerClick =
|
|
8685
|
+
const handleMarkerClick = useCallback128((marker) => {
|
|
8686
8686
|
onMarkerClick?.(marker);
|
|
8687
8687
|
if (markerClickEvent) {
|
|
8688
8688
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -25735,12 +25735,15 @@ function GameCanvas2D({
|
|
|
25735
25735
|
tickEvent,
|
|
25736
25736
|
drawEvent,
|
|
25737
25737
|
fps = 60,
|
|
25738
|
+
backgroundImage,
|
|
25739
|
+
assetBaseUrl = "",
|
|
25738
25740
|
className
|
|
25739
25741
|
}) {
|
|
25740
25742
|
const canvasRef = React80.useRef(null);
|
|
25741
25743
|
const rafRef = React80.useRef(0);
|
|
25742
25744
|
const frameRef = React80.useRef(0);
|
|
25743
25745
|
const lastTimeRef = React80.useRef(0);
|
|
25746
|
+
const imageCache = React80.useRef(/* @__PURE__ */ new Map());
|
|
25744
25747
|
const emit = useEmitEvent();
|
|
25745
25748
|
const onDrawRef = React80.useRef(onDraw);
|
|
25746
25749
|
onDrawRef.current = onDraw;
|
|
@@ -25752,6 +25755,18 @@ function GameCanvas2D({
|
|
|
25752
25755
|
drawEventRef.current = drawEvent;
|
|
25753
25756
|
const emitRef = React80.useRef(emit);
|
|
25754
25757
|
emitRef.current = emit;
|
|
25758
|
+
const loadImage = React80.useCallback((url) => {
|
|
25759
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
25760
|
+
const cached = imageCache.current.get(fullUrl);
|
|
25761
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
25762
|
+
if (!cached) {
|
|
25763
|
+
const img = new Image();
|
|
25764
|
+
img.crossOrigin = "anonymous";
|
|
25765
|
+
img.src = fullUrl;
|
|
25766
|
+
imageCache.current.set(fullUrl, img);
|
|
25767
|
+
}
|
|
25768
|
+
return null;
|
|
25769
|
+
}, [assetBaseUrl]);
|
|
25755
25770
|
React80.useEffect(() => {
|
|
25756
25771
|
const canvas = canvasRef.current;
|
|
25757
25772
|
if (!canvas) return;
|
|
@@ -25773,6 +25788,12 @@ function GameCanvas2D({
|
|
|
25773
25788
|
if (tickEventRef.current) {
|
|
25774
25789
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
25775
25790
|
}
|
|
25791
|
+
if (backgroundImage) {
|
|
25792
|
+
const bgImg = loadImage(backgroundImage);
|
|
25793
|
+
if (bgImg) {
|
|
25794
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
25795
|
+
}
|
|
25796
|
+
}
|
|
25776
25797
|
onDrawRef.current?.(ctx, frame);
|
|
25777
25798
|
if (drawEventRef.current) {
|
|
25778
25799
|
emitRef.current(drawEventRef.current, { frame });
|
|
@@ -13,10 +13,14 @@ export interface GameCanvas2DProps {
|
|
|
13
13
|
drawEvent?: string;
|
|
14
14
|
/** Target frames per second */
|
|
15
15
|
fps?: number;
|
|
16
|
+
/** Background image URL */
|
|
17
|
+
backgroundImage?: string;
|
|
18
|
+
/** Base URL prefix for asset URLs */
|
|
19
|
+
assetBaseUrl?: string;
|
|
16
20
|
/** Additional CSS classes */
|
|
17
21
|
className?: string;
|
|
18
22
|
}
|
|
19
|
-
export declare function GameCanvas2D({ width, height, onDraw, onTick, tickEvent, drawEvent, fps, className, }: GameCanvas2DProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
export declare function GameCanvas2D({ width, height, onDraw, onTick, tickEvent, drawEvent, fps, backgroundImage, assetBaseUrl, className, }: GameCanvas2DProps): import("react/jsx-runtime").JSX.Element;
|
|
20
24
|
export declare namespace GameCanvas2D {
|
|
21
25
|
var displayName: string;
|
|
22
26
|
}
|
package/dist/providers/index.cjs
CHANGED
|
@@ -10244,7 +10244,7 @@ var init_MapView = __esm({
|
|
|
10244
10244
|
shadowSize: [41, 41]
|
|
10245
10245
|
});
|
|
10246
10246
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
10247
|
-
const { useEffect: useEffect69, useRef: useRef65, useCallback:
|
|
10247
|
+
const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback114, useState: useState99 } = React86__namespace.default;
|
|
10248
10248
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
10249
10249
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
10250
10250
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -10290,7 +10290,7 @@ var init_MapView = __esm({
|
|
|
10290
10290
|
}) {
|
|
10291
10291
|
const eventBus = useEventBus2();
|
|
10292
10292
|
const [clickedPosition, setClickedPosition] = useState99(null);
|
|
10293
|
-
const handleMapClick =
|
|
10293
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
10294
10294
|
if (showClickedPin) {
|
|
10295
10295
|
setClickedPosition({ lat, lng });
|
|
10296
10296
|
}
|
|
@@ -10299,7 +10299,7 @@ var init_MapView = __esm({
|
|
|
10299
10299
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
10300
10300
|
}
|
|
10301
10301
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
10302
|
-
const handleMarkerClick =
|
|
10302
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
10303
10303
|
onMarkerClick?.(marker);
|
|
10304
10304
|
if (markerClickEvent) {
|
|
10305
10305
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -26811,12 +26811,15 @@ function GameCanvas2D({
|
|
|
26811
26811
|
tickEvent,
|
|
26812
26812
|
drawEvent,
|
|
26813
26813
|
fps = 60,
|
|
26814
|
+
backgroundImage,
|
|
26815
|
+
assetBaseUrl = "",
|
|
26814
26816
|
className
|
|
26815
26817
|
}) {
|
|
26816
26818
|
const canvasRef = React86__namespace.useRef(null);
|
|
26817
26819
|
const rafRef = React86__namespace.useRef(0);
|
|
26818
26820
|
const frameRef = React86__namespace.useRef(0);
|
|
26819
26821
|
const lastTimeRef = React86__namespace.useRef(0);
|
|
26822
|
+
const imageCache = React86__namespace.useRef(/* @__PURE__ */ new Map());
|
|
26820
26823
|
const emit = useEmitEvent();
|
|
26821
26824
|
const onDrawRef = React86__namespace.useRef(onDraw);
|
|
26822
26825
|
onDrawRef.current = onDraw;
|
|
@@ -26828,6 +26831,18 @@ function GameCanvas2D({
|
|
|
26828
26831
|
drawEventRef.current = drawEvent;
|
|
26829
26832
|
const emitRef = React86__namespace.useRef(emit);
|
|
26830
26833
|
emitRef.current = emit;
|
|
26834
|
+
const loadImage = React86__namespace.useCallback((url) => {
|
|
26835
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
26836
|
+
const cached = imageCache.current.get(fullUrl);
|
|
26837
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
26838
|
+
if (!cached) {
|
|
26839
|
+
const img = new Image();
|
|
26840
|
+
img.crossOrigin = "anonymous";
|
|
26841
|
+
img.src = fullUrl;
|
|
26842
|
+
imageCache.current.set(fullUrl, img);
|
|
26843
|
+
}
|
|
26844
|
+
return null;
|
|
26845
|
+
}, [assetBaseUrl]);
|
|
26831
26846
|
React86__namespace.useEffect(() => {
|
|
26832
26847
|
const canvas = canvasRef.current;
|
|
26833
26848
|
if (!canvas) return;
|
|
@@ -26849,6 +26864,12 @@ function GameCanvas2D({
|
|
|
26849
26864
|
if (tickEventRef.current) {
|
|
26850
26865
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
26851
26866
|
}
|
|
26867
|
+
if (backgroundImage) {
|
|
26868
|
+
const bgImg = loadImage(backgroundImage);
|
|
26869
|
+
if (bgImg) {
|
|
26870
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
26871
|
+
}
|
|
26872
|
+
}
|
|
26852
26873
|
onDrawRef.current?.(ctx, frame);
|
|
26853
26874
|
if (drawEventRef.current) {
|
|
26854
26875
|
emitRef.current(drawEventRef.current, { frame });
|
package/dist/providers/index.js
CHANGED
|
@@ -10195,7 +10195,7 @@ var init_MapView = __esm({
|
|
|
10195
10195
|
shadowSize: [41, 41]
|
|
10196
10196
|
});
|
|
10197
10197
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
10198
|
-
const { useEffect: useEffect69, useRef: useRef65, useCallback:
|
|
10198
|
+
const { useEffect: useEffect69, useRef: useRef65, useCallback: useCallback114, useState: useState99 } = React86__default;
|
|
10199
10199
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
10200
10200
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
10201
10201
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -10241,7 +10241,7 @@ var init_MapView = __esm({
|
|
|
10241
10241
|
}) {
|
|
10242
10242
|
const eventBus = useEventBus2();
|
|
10243
10243
|
const [clickedPosition, setClickedPosition] = useState99(null);
|
|
10244
|
-
const handleMapClick =
|
|
10244
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
10245
10245
|
if (showClickedPin) {
|
|
10246
10246
|
setClickedPosition({ lat, lng });
|
|
10247
10247
|
}
|
|
@@ -10250,7 +10250,7 @@ var init_MapView = __esm({
|
|
|
10250
10250
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
10251
10251
|
}
|
|
10252
10252
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
10253
|
-
const handleMarkerClick =
|
|
10253
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
10254
10254
|
onMarkerClick?.(marker);
|
|
10255
10255
|
if (markerClickEvent) {
|
|
10256
10256
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -26762,12 +26762,15 @@ function GameCanvas2D({
|
|
|
26762
26762
|
tickEvent,
|
|
26763
26763
|
drawEvent,
|
|
26764
26764
|
fps = 60,
|
|
26765
|
+
backgroundImage,
|
|
26766
|
+
assetBaseUrl = "",
|
|
26765
26767
|
className
|
|
26766
26768
|
}) {
|
|
26767
26769
|
const canvasRef = React86.useRef(null);
|
|
26768
26770
|
const rafRef = React86.useRef(0);
|
|
26769
26771
|
const frameRef = React86.useRef(0);
|
|
26770
26772
|
const lastTimeRef = React86.useRef(0);
|
|
26773
|
+
const imageCache = React86.useRef(/* @__PURE__ */ new Map());
|
|
26771
26774
|
const emit = useEmitEvent();
|
|
26772
26775
|
const onDrawRef = React86.useRef(onDraw);
|
|
26773
26776
|
onDrawRef.current = onDraw;
|
|
@@ -26779,6 +26782,18 @@ function GameCanvas2D({
|
|
|
26779
26782
|
drawEventRef.current = drawEvent;
|
|
26780
26783
|
const emitRef = React86.useRef(emit);
|
|
26781
26784
|
emitRef.current = emit;
|
|
26785
|
+
const loadImage = React86.useCallback((url) => {
|
|
26786
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
26787
|
+
const cached = imageCache.current.get(fullUrl);
|
|
26788
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
26789
|
+
if (!cached) {
|
|
26790
|
+
const img = new Image();
|
|
26791
|
+
img.crossOrigin = "anonymous";
|
|
26792
|
+
img.src = fullUrl;
|
|
26793
|
+
imageCache.current.set(fullUrl, img);
|
|
26794
|
+
}
|
|
26795
|
+
return null;
|
|
26796
|
+
}, [assetBaseUrl]);
|
|
26782
26797
|
React86.useEffect(() => {
|
|
26783
26798
|
const canvas = canvasRef.current;
|
|
26784
26799
|
if (!canvas) return;
|
|
@@ -26800,6 +26815,12 @@ function GameCanvas2D({
|
|
|
26800
26815
|
if (tickEventRef.current) {
|
|
26801
26816
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
26802
26817
|
}
|
|
26818
|
+
if (backgroundImage) {
|
|
26819
|
+
const bgImg = loadImage(backgroundImage);
|
|
26820
|
+
if (bgImg) {
|
|
26821
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
26822
|
+
}
|
|
26823
|
+
}
|
|
26803
26824
|
onDrawRef.current?.(ctx, frame);
|
|
26804
26825
|
if (drawEventRef.current) {
|
|
26805
26826
|
emitRef.current(drawEventRef.current, { frame });
|
|
@@ -21,7 +21,14 @@
|
|
|
21
21
|
*
|
|
22
22
|
* @packageDocumentation
|
|
23
23
|
*/
|
|
24
|
-
import type { OrbitalSchema } from '@almadar/core';
|
|
24
|
+
import type { OrbitalSchema, ResolvedTrait } from '@almadar/core';
|
|
25
|
+
/**
|
|
26
|
+
* Collect the `@trait.X` names referenced by a single resolved trait's
|
|
27
|
+
* render-ui effects (transitions + initial + ticks). Used to pull embed-routed
|
|
28
|
+
* sibling traits into a page's state-machine binding set so their own state
|
|
29
|
+
* machines register + subscribe (otherwise their fetch-success is never heard).
|
|
30
|
+
*/
|
|
31
|
+
export declare function collectTraitRefsFromResolvedTrait(trait: ResolvedTrait): Set<string>;
|
|
25
32
|
/**
|
|
26
33
|
* Build the flat set of trait names that are referenced via `@trait.X`
|
|
27
34
|
* by at least one trait's render-ui in the resolved schema.
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -10132,7 +10132,7 @@ var init_MapView = __esm({
|
|
|
10132
10132
|
shadowSize: [41, 41]
|
|
10133
10133
|
});
|
|
10134
10134
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
10135
|
-
const { useEffect: useEffect70, useRef: useRef65, useCallback:
|
|
10135
|
+
const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback114, useState: useState102 } = React85__namespace.default;
|
|
10136
10136
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
10137
10137
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
10138
10138
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -10178,7 +10178,7 @@ var init_MapView = __esm({
|
|
|
10178
10178
|
}) {
|
|
10179
10179
|
const eventBus = useEventBus2();
|
|
10180
10180
|
const [clickedPosition, setClickedPosition] = useState102(null);
|
|
10181
|
-
const handleMapClick =
|
|
10181
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
10182
10182
|
if (showClickedPin) {
|
|
10183
10183
|
setClickedPosition({ lat, lng });
|
|
10184
10184
|
}
|
|
@@ -10187,7 +10187,7 @@ var init_MapView = __esm({
|
|
|
10187
10187
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
10188
10188
|
}
|
|
10189
10189
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
10190
|
-
const handleMarkerClick =
|
|
10190
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
10191
10191
|
onMarkerClick?.(marker);
|
|
10192
10192
|
if (markerClickEvent) {
|
|
10193
10193
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -26516,12 +26516,15 @@ function GameCanvas2D({
|
|
|
26516
26516
|
tickEvent,
|
|
26517
26517
|
drawEvent,
|
|
26518
26518
|
fps = 60,
|
|
26519
|
+
backgroundImage,
|
|
26520
|
+
assetBaseUrl = "",
|
|
26519
26521
|
className
|
|
26520
26522
|
}) {
|
|
26521
26523
|
const canvasRef = React85__namespace.useRef(null);
|
|
26522
26524
|
const rafRef = React85__namespace.useRef(0);
|
|
26523
26525
|
const frameRef = React85__namespace.useRef(0);
|
|
26524
26526
|
const lastTimeRef = React85__namespace.useRef(0);
|
|
26527
|
+
const imageCache = React85__namespace.useRef(/* @__PURE__ */ new Map());
|
|
26525
26528
|
const emit = useEmitEvent();
|
|
26526
26529
|
const onDrawRef = React85__namespace.useRef(onDraw);
|
|
26527
26530
|
onDrawRef.current = onDraw;
|
|
@@ -26533,6 +26536,18 @@ function GameCanvas2D({
|
|
|
26533
26536
|
drawEventRef.current = drawEvent;
|
|
26534
26537
|
const emitRef = React85__namespace.useRef(emit);
|
|
26535
26538
|
emitRef.current = emit;
|
|
26539
|
+
const loadImage = React85__namespace.useCallback((url) => {
|
|
26540
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
26541
|
+
const cached = imageCache.current.get(fullUrl);
|
|
26542
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
26543
|
+
if (!cached) {
|
|
26544
|
+
const img = new Image();
|
|
26545
|
+
img.crossOrigin = "anonymous";
|
|
26546
|
+
img.src = fullUrl;
|
|
26547
|
+
imageCache.current.set(fullUrl, img);
|
|
26548
|
+
}
|
|
26549
|
+
return null;
|
|
26550
|
+
}, [assetBaseUrl]);
|
|
26536
26551
|
React85__namespace.useEffect(() => {
|
|
26537
26552
|
const canvas = canvasRef.current;
|
|
26538
26553
|
if (!canvas) return;
|
|
@@ -26554,6 +26569,12 @@ function GameCanvas2D({
|
|
|
26554
26569
|
if (tickEventRef.current) {
|
|
26555
26570
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
26556
26571
|
}
|
|
26572
|
+
if (backgroundImage) {
|
|
26573
|
+
const bgImg = loadImage(backgroundImage);
|
|
26574
|
+
if (bgImg) {
|
|
26575
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
26576
|
+
}
|
|
26577
|
+
}
|
|
26557
26578
|
onDrawRef.current?.(ctx, frame);
|
|
26558
26579
|
if (drawEventRef.current) {
|
|
26559
26580
|
emitRef.current(drawEventRef.current, { frame });
|
|
@@ -48512,6 +48533,16 @@ function collectTraitRefsFromEffects(effects, into) {
|
|
|
48512
48533
|
}
|
|
48513
48534
|
}
|
|
48514
48535
|
}
|
|
48536
|
+
function collectTraitRefsFromResolvedTrait(trait) {
|
|
48537
|
+
const out = /* @__PURE__ */ new Set();
|
|
48538
|
+
for (const transition of trait.transitions ?? []) {
|
|
48539
|
+
collectTraitRefsFromEffects(transition.effects, out);
|
|
48540
|
+
}
|
|
48541
|
+
for (const tick of trait.ticks ?? []) {
|
|
48542
|
+
collectTraitRefsFromEffects(tick.effects, out);
|
|
48543
|
+
}
|
|
48544
|
+
return out;
|
|
48545
|
+
}
|
|
48515
48546
|
function collectEmbeddedTraits(schema) {
|
|
48516
48547
|
const out = /* @__PURE__ */ new Set();
|
|
48517
48548
|
if (!schema?.orbitals) return out;
|
|
@@ -48544,6 +48575,40 @@ function collectEmbeddedTraits(schema) {
|
|
|
48544
48575
|
return out;
|
|
48545
48576
|
}
|
|
48546
48577
|
|
|
48578
|
+
// runtime/orbitalsByTrait.ts
|
|
48579
|
+
function buildOrbitalsByTrait(schema, resolvedPages = []) {
|
|
48580
|
+
const map = {};
|
|
48581
|
+
if (!schema?.orbitals) return map;
|
|
48582
|
+
const pagePathToOrbital = {};
|
|
48583
|
+
for (const orb of schema.orbitals) {
|
|
48584
|
+
for (const traitRef of orb.traits ?? []) {
|
|
48585
|
+
let traitName;
|
|
48586
|
+
if (typeof traitRef === "string") {
|
|
48587
|
+
const parts = traitRef.split(".");
|
|
48588
|
+
traitName = parts[parts.length - 1];
|
|
48589
|
+
} else if (typeof traitRef.ref === "string") {
|
|
48590
|
+
const parts = traitRef.ref.split(".");
|
|
48591
|
+
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
48592
|
+
} else if (typeof traitRef.name === "string") {
|
|
48593
|
+
traitName = traitRef.name;
|
|
48594
|
+
}
|
|
48595
|
+
if (traitName) map[traitName] = orb.name;
|
|
48596
|
+
}
|
|
48597
|
+
for (const pg of orb.pages ?? []) {
|
|
48598
|
+
const path = typeof pg === "string" ? pg : pg?.path;
|
|
48599
|
+
if (path) pagePathToOrbital[path] = orb.name;
|
|
48600
|
+
}
|
|
48601
|
+
}
|
|
48602
|
+
for (const page of resolvedPages) {
|
|
48603
|
+
const orbital = page.path ? pagePathToOrbital[page.path] : void 0;
|
|
48604
|
+
if (!orbital) continue;
|
|
48605
|
+
for (const traitName of page.traitNames) {
|
|
48606
|
+
if (traitName && !(traitName in map)) map[traitName] = orbital;
|
|
48607
|
+
}
|
|
48608
|
+
}
|
|
48609
|
+
return map;
|
|
48610
|
+
}
|
|
48611
|
+
|
|
48547
48612
|
// runtime/OrbPreview.tsx
|
|
48548
48613
|
init_EntitySchemaContext();
|
|
48549
48614
|
|
|
@@ -49316,50 +49381,64 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
49316
49381
|
return null;
|
|
49317
49382
|
}
|
|
49318
49383
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
49319
|
-
const { traits: traits2, allEntities, ir } = useResolvedSchema(schema, pageName);
|
|
49384
|
+
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
49320
49385
|
const allPageTraits = React85.useMemo(() => {
|
|
49321
|
-
|
|
49322
|
-
if (
|
|
49323
|
-
|
|
49324
|
-
if (!
|
|
49325
|
-
|
|
49326
|
-
|
|
49327
|
-
|
|
49328
|
-
|
|
49329
|
-
|
|
49330
|
-
|
|
49331
|
-
firstPageTraits
|
|
49332
|
-
|
|
49333
|
-
|
|
49334
|
-
|
|
49335
|
-
|
|
49386
|
+
let base;
|
|
49387
|
+
if (pageName && traits2.length > 0) {
|
|
49388
|
+
base = traits2;
|
|
49389
|
+
} else if (!ir?.pages || ir.pages.size <= 1) {
|
|
49390
|
+
base = traits2;
|
|
49391
|
+
} else {
|
|
49392
|
+
const firstPage = ir.pages.values().next().value;
|
|
49393
|
+
if (!firstPage) {
|
|
49394
|
+
base = traits2;
|
|
49395
|
+
} else {
|
|
49396
|
+
const firstPageTraits = [];
|
|
49397
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49398
|
+
for (const binding of firstPage.traits) {
|
|
49399
|
+
const name = binding.trait.name;
|
|
49400
|
+
if (name && !seen.has(name)) {
|
|
49401
|
+
seen.add(name);
|
|
49402
|
+
firstPageTraits.push(binding);
|
|
49403
|
+
}
|
|
49404
|
+
}
|
|
49405
|
+
base = firstPageTraits.length > 0 ? firstPageTraits : traits2;
|
|
49406
|
+
}
|
|
49407
|
+
}
|
|
49408
|
+
const byName = new Set(base.map((b) => b.trait.name));
|
|
49409
|
+
const extra = [];
|
|
49410
|
+
const queue = [...base];
|
|
49411
|
+
while (queue.length > 0) {
|
|
49412
|
+
const binding = queue.shift();
|
|
49413
|
+
if (!binding) continue;
|
|
49414
|
+
for (const refName of collectTraitRefsFromResolvedTrait(binding.trait)) {
|
|
49415
|
+
if (byName.has(refName)) continue;
|
|
49416
|
+
const rt = allTraits.get(refName);
|
|
49417
|
+
if (!rt) continue;
|
|
49418
|
+
byName.add(refName);
|
|
49419
|
+
const sibling = { trait: rt, linkedEntity: rt.linkedEntity };
|
|
49420
|
+
extra.push(sibling);
|
|
49421
|
+
queue.push(sibling);
|
|
49422
|
+
}
|
|
49423
|
+
}
|
|
49424
|
+
return extra.length > 0 ? [...base, ...extra] : base;
|
|
49425
|
+
}, [ir, traits2, pageName, allTraits]);
|
|
49336
49426
|
React85.useMemo(() => {
|
|
49337
49427
|
const parsed = schema;
|
|
49338
49428
|
const orbitals = parsed?.orbitals;
|
|
49339
49429
|
if (!orbitals) return [];
|
|
49340
49430
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
49341
49431
|
}, [schema]);
|
|
49342
|
-
const orbitalsByTrait = React85.useMemo(
|
|
49343
|
-
|
|
49344
|
-
|
|
49345
|
-
|
|
49346
|
-
|
|
49347
|
-
|
|
49348
|
-
|
|
49349
|
-
|
|
49350
|
-
|
|
49351
|
-
|
|
49352
|
-
} else if ("ref" in traitRef && typeof traitRef.ref === "string") {
|
|
49353
|
-
const parts = traitRef.ref.split(".");
|
|
49354
|
-
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
49355
|
-
} else if ("name" in traitRef && typeof traitRef.name === "string") {
|
|
49356
|
-
traitName = traitRef.name;
|
|
49357
|
-
}
|
|
49358
|
-
if (traitName) map[traitName] = orb.name;
|
|
49359
|
-
}
|
|
49360
|
-
}
|
|
49361
|
-
return map;
|
|
49362
|
-
}, [schema]);
|
|
49432
|
+
const orbitalsByTrait = React85.useMemo(
|
|
49433
|
+
() => buildOrbitalsByTrait(
|
|
49434
|
+
schema,
|
|
49435
|
+
ir ? Array.from(ir.pages.values()).map((p2) => ({
|
|
49436
|
+
path: p2.path,
|
|
49437
|
+
traitNames: p2.traits.map((b) => b.trait.name)
|
|
49438
|
+
})) : []
|
|
49439
|
+
),
|
|
49440
|
+
[schema, ir]
|
|
49441
|
+
);
|
|
49363
49442
|
const traitLinkedEntitiesMap = React85.useMemo(() => {
|
|
49364
49443
|
const map = /* @__PURE__ */ new Map();
|
|
49365
49444
|
if (ir) {
|
package/dist/runtime/index.js
CHANGED
|
@@ -10083,7 +10083,7 @@ var init_MapView = __esm({
|
|
|
10083
10083
|
shadowSize: [41, 41]
|
|
10084
10084
|
});
|
|
10085
10085
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
10086
|
-
const { useEffect: useEffect70, useRef: useRef65, useCallback:
|
|
10086
|
+
const { useEffect: useEffect70, useRef: useRef65, useCallback: useCallback114, useState: useState102 } = React85__default;
|
|
10087
10087
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
10088
10088
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
10089
10089
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
@@ -10129,7 +10129,7 @@ var init_MapView = __esm({
|
|
|
10129
10129
|
}) {
|
|
10130
10130
|
const eventBus = useEventBus2();
|
|
10131
10131
|
const [clickedPosition, setClickedPosition] = useState102(null);
|
|
10132
|
-
const handleMapClick =
|
|
10132
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
10133
10133
|
if (showClickedPin) {
|
|
10134
10134
|
setClickedPosition({ lat, lng });
|
|
10135
10135
|
}
|
|
@@ -10138,7 +10138,7 @@ var init_MapView = __esm({
|
|
|
10138
10138
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
10139
10139
|
}
|
|
10140
10140
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
10141
|
-
const handleMarkerClick =
|
|
10141
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
10142
10142
|
onMarkerClick?.(marker);
|
|
10143
10143
|
if (markerClickEvent) {
|
|
10144
10144
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -26467,12 +26467,15 @@ function GameCanvas2D({
|
|
|
26467
26467
|
tickEvent,
|
|
26468
26468
|
drawEvent,
|
|
26469
26469
|
fps = 60,
|
|
26470
|
+
backgroundImage,
|
|
26471
|
+
assetBaseUrl = "",
|
|
26470
26472
|
className
|
|
26471
26473
|
}) {
|
|
26472
26474
|
const canvasRef = React85.useRef(null);
|
|
26473
26475
|
const rafRef = React85.useRef(0);
|
|
26474
26476
|
const frameRef = React85.useRef(0);
|
|
26475
26477
|
const lastTimeRef = React85.useRef(0);
|
|
26478
|
+
const imageCache = React85.useRef(/* @__PURE__ */ new Map());
|
|
26476
26479
|
const emit = useEmitEvent();
|
|
26477
26480
|
const onDrawRef = React85.useRef(onDraw);
|
|
26478
26481
|
onDrawRef.current = onDraw;
|
|
@@ -26484,6 +26487,18 @@ function GameCanvas2D({
|
|
|
26484
26487
|
drawEventRef.current = drawEvent;
|
|
26485
26488
|
const emitRef = React85.useRef(emit);
|
|
26486
26489
|
emitRef.current = emit;
|
|
26490
|
+
const loadImage = React85.useCallback((url) => {
|
|
26491
|
+
const fullUrl = url.startsWith("http") ? url : `${assetBaseUrl}${url}`;
|
|
26492
|
+
const cached = imageCache.current.get(fullUrl);
|
|
26493
|
+
if (cached?.complete && cached.naturalWidth > 0) return cached;
|
|
26494
|
+
if (!cached) {
|
|
26495
|
+
const img = new Image();
|
|
26496
|
+
img.crossOrigin = "anonymous";
|
|
26497
|
+
img.src = fullUrl;
|
|
26498
|
+
imageCache.current.set(fullUrl, img);
|
|
26499
|
+
}
|
|
26500
|
+
return null;
|
|
26501
|
+
}, [assetBaseUrl]);
|
|
26487
26502
|
React85.useEffect(() => {
|
|
26488
26503
|
const canvas = canvasRef.current;
|
|
26489
26504
|
if (!canvas) return;
|
|
@@ -26505,6 +26520,12 @@ function GameCanvas2D({
|
|
|
26505
26520
|
if (tickEventRef.current) {
|
|
26506
26521
|
emitRef.current(tickEventRef.current, { dt, frame });
|
|
26507
26522
|
}
|
|
26523
|
+
if (backgroundImage) {
|
|
26524
|
+
const bgImg = loadImage(backgroundImage);
|
|
26525
|
+
if (bgImg) {
|
|
26526
|
+
ctx.drawImage(bgImg, 0, 0, width, height);
|
|
26527
|
+
}
|
|
26528
|
+
}
|
|
26508
26529
|
onDrawRef.current?.(ctx, frame);
|
|
26509
26530
|
if (drawEventRef.current) {
|
|
26510
26531
|
emitRef.current(drawEventRef.current, { frame });
|
|
@@ -48463,6 +48484,16 @@ function collectTraitRefsFromEffects(effects, into) {
|
|
|
48463
48484
|
}
|
|
48464
48485
|
}
|
|
48465
48486
|
}
|
|
48487
|
+
function collectTraitRefsFromResolvedTrait(trait) {
|
|
48488
|
+
const out = /* @__PURE__ */ new Set();
|
|
48489
|
+
for (const transition of trait.transitions ?? []) {
|
|
48490
|
+
collectTraitRefsFromEffects(transition.effects, out);
|
|
48491
|
+
}
|
|
48492
|
+
for (const tick of trait.ticks ?? []) {
|
|
48493
|
+
collectTraitRefsFromEffects(tick.effects, out);
|
|
48494
|
+
}
|
|
48495
|
+
return out;
|
|
48496
|
+
}
|
|
48466
48497
|
function collectEmbeddedTraits(schema) {
|
|
48467
48498
|
const out = /* @__PURE__ */ new Set();
|
|
48468
48499
|
if (!schema?.orbitals) return out;
|
|
@@ -48495,6 +48526,40 @@ function collectEmbeddedTraits(schema) {
|
|
|
48495
48526
|
return out;
|
|
48496
48527
|
}
|
|
48497
48528
|
|
|
48529
|
+
// runtime/orbitalsByTrait.ts
|
|
48530
|
+
function buildOrbitalsByTrait(schema, resolvedPages = []) {
|
|
48531
|
+
const map = {};
|
|
48532
|
+
if (!schema?.orbitals) return map;
|
|
48533
|
+
const pagePathToOrbital = {};
|
|
48534
|
+
for (const orb of schema.orbitals) {
|
|
48535
|
+
for (const traitRef of orb.traits ?? []) {
|
|
48536
|
+
let traitName;
|
|
48537
|
+
if (typeof traitRef === "string") {
|
|
48538
|
+
const parts = traitRef.split(".");
|
|
48539
|
+
traitName = parts[parts.length - 1];
|
|
48540
|
+
} else if (typeof traitRef.ref === "string") {
|
|
48541
|
+
const parts = traitRef.ref.split(".");
|
|
48542
|
+
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
48543
|
+
} else if (typeof traitRef.name === "string") {
|
|
48544
|
+
traitName = traitRef.name;
|
|
48545
|
+
}
|
|
48546
|
+
if (traitName) map[traitName] = orb.name;
|
|
48547
|
+
}
|
|
48548
|
+
for (const pg of orb.pages ?? []) {
|
|
48549
|
+
const path = typeof pg === "string" ? pg : pg?.path;
|
|
48550
|
+
if (path) pagePathToOrbital[path] = orb.name;
|
|
48551
|
+
}
|
|
48552
|
+
}
|
|
48553
|
+
for (const page of resolvedPages) {
|
|
48554
|
+
const orbital = page.path ? pagePathToOrbital[page.path] : void 0;
|
|
48555
|
+
if (!orbital) continue;
|
|
48556
|
+
for (const traitName of page.traitNames) {
|
|
48557
|
+
if (traitName && !(traitName in map)) map[traitName] = orbital;
|
|
48558
|
+
}
|
|
48559
|
+
}
|
|
48560
|
+
return map;
|
|
48561
|
+
}
|
|
48562
|
+
|
|
48498
48563
|
// runtime/OrbPreview.tsx
|
|
48499
48564
|
init_EntitySchemaContext();
|
|
48500
48565
|
|
|
@@ -49267,50 +49332,64 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate, onLocalFa
|
|
|
49267
49332
|
return null;
|
|
49268
49333
|
}
|
|
49269
49334
|
function SchemaRunner({ schema, serverUrl, transport, mockData, pageName, onNavigate, onLocalFallback, persistence }) {
|
|
49270
|
-
const { traits: traits2, allEntities, ir } = useResolvedSchema(schema, pageName);
|
|
49335
|
+
const { traits: traits2, allEntities, allTraits, ir } = useResolvedSchema(schema, pageName);
|
|
49271
49336
|
const allPageTraits = useMemo(() => {
|
|
49272
|
-
|
|
49273
|
-
if (
|
|
49274
|
-
|
|
49275
|
-
if (!
|
|
49276
|
-
|
|
49277
|
-
|
|
49278
|
-
|
|
49279
|
-
|
|
49280
|
-
|
|
49281
|
-
|
|
49282
|
-
firstPageTraits
|
|
49283
|
-
|
|
49284
|
-
|
|
49285
|
-
|
|
49286
|
-
|
|
49337
|
+
let base;
|
|
49338
|
+
if (pageName && traits2.length > 0) {
|
|
49339
|
+
base = traits2;
|
|
49340
|
+
} else if (!ir?.pages || ir.pages.size <= 1) {
|
|
49341
|
+
base = traits2;
|
|
49342
|
+
} else {
|
|
49343
|
+
const firstPage = ir.pages.values().next().value;
|
|
49344
|
+
if (!firstPage) {
|
|
49345
|
+
base = traits2;
|
|
49346
|
+
} else {
|
|
49347
|
+
const firstPageTraits = [];
|
|
49348
|
+
const seen = /* @__PURE__ */ new Set();
|
|
49349
|
+
for (const binding of firstPage.traits) {
|
|
49350
|
+
const name = binding.trait.name;
|
|
49351
|
+
if (name && !seen.has(name)) {
|
|
49352
|
+
seen.add(name);
|
|
49353
|
+
firstPageTraits.push(binding);
|
|
49354
|
+
}
|
|
49355
|
+
}
|
|
49356
|
+
base = firstPageTraits.length > 0 ? firstPageTraits : traits2;
|
|
49357
|
+
}
|
|
49358
|
+
}
|
|
49359
|
+
const byName = new Set(base.map((b) => b.trait.name));
|
|
49360
|
+
const extra = [];
|
|
49361
|
+
const queue = [...base];
|
|
49362
|
+
while (queue.length > 0) {
|
|
49363
|
+
const binding = queue.shift();
|
|
49364
|
+
if (!binding) continue;
|
|
49365
|
+
for (const refName of collectTraitRefsFromResolvedTrait(binding.trait)) {
|
|
49366
|
+
if (byName.has(refName)) continue;
|
|
49367
|
+
const rt = allTraits.get(refName);
|
|
49368
|
+
if (!rt) continue;
|
|
49369
|
+
byName.add(refName);
|
|
49370
|
+
const sibling = { trait: rt, linkedEntity: rt.linkedEntity };
|
|
49371
|
+
extra.push(sibling);
|
|
49372
|
+
queue.push(sibling);
|
|
49373
|
+
}
|
|
49374
|
+
}
|
|
49375
|
+
return extra.length > 0 ? [...base, ...extra] : base;
|
|
49376
|
+
}, [ir, traits2, pageName, allTraits]);
|
|
49287
49377
|
useMemo(() => {
|
|
49288
49378
|
const parsed = schema;
|
|
49289
49379
|
const orbitals = parsed?.orbitals;
|
|
49290
49380
|
if (!orbitals) return [];
|
|
49291
49381
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
49292
49382
|
}, [schema]);
|
|
49293
|
-
const orbitalsByTrait = useMemo(
|
|
49294
|
-
|
|
49295
|
-
|
|
49296
|
-
|
|
49297
|
-
|
|
49298
|
-
|
|
49299
|
-
|
|
49300
|
-
|
|
49301
|
-
|
|
49302
|
-
|
|
49303
|
-
} else if ("ref" in traitRef && typeof traitRef.ref === "string") {
|
|
49304
|
-
const parts = traitRef.ref.split(".");
|
|
49305
|
-
traitName = traitRef.name ?? parts[parts.length - 1];
|
|
49306
|
-
} else if ("name" in traitRef && typeof traitRef.name === "string") {
|
|
49307
|
-
traitName = traitRef.name;
|
|
49308
|
-
}
|
|
49309
|
-
if (traitName) map[traitName] = orb.name;
|
|
49310
|
-
}
|
|
49311
|
-
}
|
|
49312
|
-
return map;
|
|
49313
|
-
}, [schema]);
|
|
49383
|
+
const orbitalsByTrait = useMemo(
|
|
49384
|
+
() => buildOrbitalsByTrait(
|
|
49385
|
+
schema,
|
|
49386
|
+
ir ? Array.from(ir.pages.values()).map((p2) => ({
|
|
49387
|
+
path: p2.path,
|
|
49388
|
+
traitNames: p2.traits.map((b) => b.trait.name)
|
|
49389
|
+
})) : []
|
|
49390
|
+
),
|
|
49391
|
+
[schema, ir]
|
|
49392
|
+
);
|
|
49314
49393
|
const traitLinkedEntitiesMap = useMemo(() => {
|
|
49315
49394
|
const map = /* @__PURE__ */ new Map();
|
|
49316
49395
|
if (ir) {
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build the `trait name → owning orbital` map used to form the qualified
|
|
3
|
+
* `UI:<orbital>.<trait>.<event>` bus keys that trait state machines subscribe
|
|
4
|
+
* to. Pure + dependency-free so it can be unit-tested without a React render.
|
|
5
|
+
*
|
|
6
|
+
* Critically, it backfills from the RESOLVED page bindings, not just the source
|
|
7
|
+
* `schema.orbitals[].traits`. An auto-pulled sibling trait (e.g. an embedded
|
|
8
|
+
* `@trait.X` calendar lifted into the orbital by the compiler's sibling-pull)
|
|
9
|
+
* is absent from the source orbital's `traits[]`, so a source-only map misses
|
|
10
|
+
* it — leaving its self-subscription unregistered and its own fetch-success
|
|
11
|
+
* (e.g. `CalendarEventLoaded`) unheard, so the trait sticks in `loading`. A
|
|
12
|
+
* pulled sibling lands in the same orbital as the page that references it, so
|
|
13
|
+
* we backfill from the resolved page's owning orbital. Source-declared mappings
|
|
14
|
+
* win; the IR only fills gaps.
|
|
15
|
+
*/
|
|
16
|
+
export interface OrbitalsByTraitSchema {
|
|
17
|
+
orbitals?: ReadonlyArray<{
|
|
18
|
+
name: string;
|
|
19
|
+
traits?: ReadonlyArray<string | {
|
|
20
|
+
ref?: string;
|
|
21
|
+
name?: string;
|
|
22
|
+
}>;
|
|
23
|
+
pages?: ReadonlyArray<string | {
|
|
24
|
+
path?: string;
|
|
25
|
+
}>;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
export interface ResolvedPageTraits {
|
|
29
|
+
/** Page route path, matched against the source orbital's page paths. */
|
|
30
|
+
path?: string;
|
|
31
|
+
/** Resolved trait names mounted on the page (includes pulled siblings). */
|
|
32
|
+
traitNames: readonly string[];
|
|
33
|
+
}
|
|
34
|
+
export declare function buildOrbitalsByTrait(schema: OrbitalsByTraitSchema | undefined, resolvedPages?: ReadonlyArray<ResolvedPageTraits>): Record<string, string>;
|