@almadar/ui 2.29.0 → 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/components/index.cjs +82 -29
- package/dist/components/index.js +82 -29
- package/dist/providers/EntityStoreProvider.d.ts +2 -0
- package/dist/runtime/ServerBridge.d.ts +2 -0
- package/dist/runtime/createClientEffectHandlers.d.ts +0 -1
- package/dist/runtime/index.cjs +66 -50
- package/dist/runtime/index.d.ts +0 -1
- package/dist/runtime/index.js +69 -52
- package/package.json +1 -1
- package/dist/runtime/enrichFromResponse.d.ts +0 -21
|
@@ -6059,43 +6059,43 @@ function useQuerySingleton(query) {
|
|
|
6059
6059
|
if (!query) {
|
|
6060
6060
|
return null;
|
|
6061
6061
|
}
|
|
6062
|
-
const
|
|
6062
|
+
const store2 = React91.useMemo(() => getOrCreateStore(query), [query]);
|
|
6063
6063
|
React91.useMemo(() => {
|
|
6064
6064
|
const listener = () => forceUpdate({});
|
|
6065
|
-
|
|
6065
|
+
store2.listeners.add(listener);
|
|
6066
6066
|
return () => {
|
|
6067
|
-
|
|
6067
|
+
store2.listeners.delete(listener);
|
|
6068
6068
|
};
|
|
6069
|
-
}, [
|
|
6069
|
+
}, [store2]);
|
|
6070
6070
|
const notifyListeners = React91.useCallback(() => {
|
|
6071
|
-
|
|
6072
|
-
}, [
|
|
6071
|
+
store2.listeners.forEach((listener) => listener());
|
|
6072
|
+
}, [store2]);
|
|
6073
6073
|
const setSearch = React91.useCallback((value) => {
|
|
6074
|
-
|
|
6074
|
+
store2.search = value;
|
|
6075
6075
|
notifyListeners();
|
|
6076
|
-
}, [
|
|
6076
|
+
}, [store2, notifyListeners]);
|
|
6077
6077
|
const setFilter = React91.useCallback((key, value) => {
|
|
6078
|
-
|
|
6078
|
+
store2.filters = { ...store2.filters, [key]: value };
|
|
6079
6079
|
notifyListeners();
|
|
6080
|
-
}, [
|
|
6080
|
+
}, [store2, notifyListeners]);
|
|
6081
6081
|
const clearFilters = React91.useCallback(() => {
|
|
6082
|
-
|
|
6083
|
-
|
|
6082
|
+
store2.filters = {};
|
|
6083
|
+
store2.search = "";
|
|
6084
6084
|
notifyListeners();
|
|
6085
|
-
}, [
|
|
6085
|
+
}, [store2, notifyListeners]);
|
|
6086
6086
|
const setSort = React91.useCallback((field, direction) => {
|
|
6087
|
-
|
|
6088
|
-
|
|
6087
|
+
store2.sortField = field;
|
|
6088
|
+
store2.sortDirection = direction;
|
|
6089
6089
|
notifyListeners();
|
|
6090
|
-
}, [
|
|
6090
|
+
}, [store2, notifyListeners]);
|
|
6091
6091
|
return {
|
|
6092
|
-
search:
|
|
6092
|
+
search: store2.search,
|
|
6093
6093
|
setSearch,
|
|
6094
|
-
filters:
|
|
6094
|
+
filters: store2.filters,
|
|
6095
6095
|
setFilter,
|
|
6096
6096
|
clearFilters,
|
|
6097
|
-
sortField:
|
|
6098
|
-
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
|
|
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(
|
|
27527
|
+
timerRef.current = setTimeout(advance2, stepDurationMs);
|
|
27528
27528
|
}
|
|
27529
27529
|
};
|
|
27530
|
-
timerRef.current = setTimeout(
|
|
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, { ...
|
|
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
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
37689
|
+
const entities2 = React91.useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
|
|
37637
37690
|
return [...entities2.values()].find((e) => e.type === type);
|
|
37638
37691
|
}
|
|
37639
37692
|
function usePlayer() {
|
package/dist/components/index.js
CHANGED
|
@@ -6029,43 +6029,43 @@ function useQuerySingleton(query) {
|
|
|
6029
6029
|
if (!query) {
|
|
6030
6030
|
return null;
|
|
6031
6031
|
}
|
|
6032
|
-
const
|
|
6032
|
+
const store2 = useMemo(() => getOrCreateStore(query), [query]);
|
|
6033
6033
|
useMemo(() => {
|
|
6034
6034
|
const listener = () => forceUpdate({});
|
|
6035
|
-
|
|
6035
|
+
store2.listeners.add(listener);
|
|
6036
6036
|
return () => {
|
|
6037
|
-
|
|
6037
|
+
store2.listeners.delete(listener);
|
|
6038
6038
|
};
|
|
6039
|
-
}, [
|
|
6039
|
+
}, [store2]);
|
|
6040
6040
|
const notifyListeners = useCallback(() => {
|
|
6041
|
-
|
|
6042
|
-
}, [
|
|
6041
|
+
store2.listeners.forEach((listener) => listener());
|
|
6042
|
+
}, [store2]);
|
|
6043
6043
|
const setSearch = useCallback((value) => {
|
|
6044
|
-
|
|
6044
|
+
store2.search = value;
|
|
6045
6045
|
notifyListeners();
|
|
6046
|
-
}, [
|
|
6046
|
+
}, [store2, notifyListeners]);
|
|
6047
6047
|
const setFilter = useCallback((key, value) => {
|
|
6048
|
-
|
|
6048
|
+
store2.filters = { ...store2.filters, [key]: value };
|
|
6049
6049
|
notifyListeners();
|
|
6050
|
-
}, [
|
|
6050
|
+
}, [store2, notifyListeners]);
|
|
6051
6051
|
const clearFilters = useCallback(() => {
|
|
6052
|
-
|
|
6053
|
-
|
|
6052
|
+
store2.filters = {};
|
|
6053
|
+
store2.search = "";
|
|
6054
6054
|
notifyListeners();
|
|
6055
|
-
}, [
|
|
6055
|
+
}, [store2, notifyListeners]);
|
|
6056
6056
|
const setSort = useCallback((field, direction) => {
|
|
6057
|
-
|
|
6058
|
-
|
|
6057
|
+
store2.sortField = field;
|
|
6058
|
+
store2.sortDirection = direction;
|
|
6059
6059
|
notifyListeners();
|
|
6060
|
-
}, [
|
|
6060
|
+
}, [store2, notifyListeners]);
|
|
6061
6061
|
return {
|
|
6062
|
-
search:
|
|
6062
|
+
search: store2.search,
|
|
6063
6063
|
setSearch,
|
|
6064
|
-
filters:
|
|
6064
|
+
filters: store2.filters,
|
|
6065
6065
|
setFilter,
|
|
6066
6066
|
clearFilters,
|
|
6067
|
-
sortField:
|
|
6068
|
-
sortDirection:
|
|
6067
|
+
sortField: store2.sortField,
|
|
6068
|
+
sortDirection: store2.sortDirection,
|
|
6069
6069
|
setSort
|
|
6070
6070
|
};
|
|
6071
6071
|
}
|
|
@@ -27463,7 +27463,7 @@ function SequencerBoard({
|
|
|
27463
27463
|
setPlayState("playing");
|
|
27464
27464
|
setCurrentStep(0);
|
|
27465
27465
|
let step = 0;
|
|
27466
|
-
const
|
|
27466
|
+
const advance2 = () => {
|
|
27467
27467
|
step++;
|
|
27468
27468
|
if (step >= entity.maxSlots) {
|
|
27469
27469
|
const playerSeq = slots.map((s) => s?.id);
|
|
@@ -27494,10 +27494,10 @@ function SequencerBoard({
|
|
|
27494
27494
|
}
|
|
27495
27495
|
} else {
|
|
27496
27496
|
setCurrentStep(step);
|
|
27497
|
-
timerRef.current = setTimeout(
|
|
27497
|
+
timerRef.current = setTimeout(advance2, stepDurationMs);
|
|
27498
27498
|
}
|
|
27499
27499
|
};
|
|
27500
|
-
timerRef.current = setTimeout(
|
|
27500
|
+
timerRef.current = setTimeout(advance2, stepDurationMs);
|
|
27501
27501
|
}, [canPlay, slots, entity.maxSlots, entity.solutions, stepDurationMs, playEvent, completeEvent, emit]);
|
|
27502
27502
|
const machine = {
|
|
27503
27503
|
name: entity.title,
|
|
@@ -29606,6 +29606,55 @@ function calculateDamage(attack, defense, isDefending = false, criticalChance =
|
|
|
29606
29606
|
function generateCombatMessage(event) {
|
|
29607
29607
|
return event.message;
|
|
29608
29608
|
}
|
|
29609
|
+
var store = /* @__PURE__ */ new Map();
|
|
29610
|
+
var storeListeners = /* @__PURE__ */ new Set();
|
|
29611
|
+
var watchCallbacks = /* @__PURE__ */ new Map();
|
|
29612
|
+
function advance(entityType, data) {
|
|
29613
|
+
const prev = store.get(entityType);
|
|
29614
|
+
const oldData = prev?.data ?? [];
|
|
29615
|
+
store.set(entityType, { data, version: (prev?.version ?? 0) + 1 });
|
|
29616
|
+
for (const listener of storeListeners) {
|
|
29617
|
+
listener();
|
|
29618
|
+
}
|
|
29619
|
+
const cbs = watchCallbacks.get(entityType);
|
|
29620
|
+
if (cbs) {
|
|
29621
|
+
for (const cb of cbs) {
|
|
29622
|
+
try {
|
|
29623
|
+
cb(oldData, data);
|
|
29624
|
+
} catch {
|
|
29625
|
+
}
|
|
29626
|
+
}
|
|
29627
|
+
}
|
|
29628
|
+
}
|
|
29629
|
+
function getSnapshot2(entityType) {
|
|
29630
|
+
return store.get(entityType)?.data ?? [];
|
|
29631
|
+
}
|
|
29632
|
+
function getVersion(entityType) {
|
|
29633
|
+
return store.get(entityType)?.version ?? 0;
|
|
29634
|
+
}
|
|
29635
|
+
function subscribeToStore(listener) {
|
|
29636
|
+
storeListeners.add(listener);
|
|
29637
|
+
return () => {
|
|
29638
|
+
storeListeners.delete(listener);
|
|
29639
|
+
};
|
|
29640
|
+
}
|
|
29641
|
+
function useEntityRef(entityType) {
|
|
29642
|
+
const versionRef = useRef(0);
|
|
29643
|
+
const dataRef = useRef([]);
|
|
29644
|
+
const getSnapshotStable = React91__default.useCallback(() => {
|
|
29645
|
+
const currentVersion = getVersion(entityType);
|
|
29646
|
+
if (currentVersion !== versionRef.current) {
|
|
29647
|
+
versionRef.current = currentVersion;
|
|
29648
|
+
dataRef.current = getSnapshot2(entityType);
|
|
29649
|
+
}
|
|
29650
|
+
return dataRef.current;
|
|
29651
|
+
}, [entityType]);
|
|
29652
|
+
return useSyncExternalStore(subscribeToStore, getSnapshotStable, () => []);
|
|
29653
|
+
}
|
|
29654
|
+
createContext({
|
|
29655
|
+
advance,
|
|
29656
|
+
getSnapshot: getSnapshot2
|
|
29657
|
+
});
|
|
29609
29658
|
var ClientEffectConfigContext = createContext(null);
|
|
29610
29659
|
ClientEffectConfigContext.Provider;
|
|
29611
29660
|
|
|
@@ -35006,6 +35055,9 @@ function SlotContentRenderer({
|
|
|
35006
35055
|
content,
|
|
35007
35056
|
onDismiss
|
|
35008
35057
|
}) {
|
|
35058
|
+
const entityProp = content.props.entity;
|
|
35059
|
+
const entityType = typeof entityProp === "string" ? entityProp : "";
|
|
35060
|
+
const storeData = useEntityRef(entityType);
|
|
35009
35061
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
35010
35062
|
if (PatternComponent) {
|
|
35011
35063
|
const childrenConfig = content.props.children;
|
|
@@ -35013,13 +35065,14 @@ function SlotContentRenderer({
|
|
|
35013
35065
|
const renderedChildren = hasChildren ? renderPatternChildren(childrenConfig, onDismiss, content.id) : void 0;
|
|
35014
35066
|
const { children: _childrenConfig, ...restProps } = content.props;
|
|
35015
35067
|
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
35068
|
+
const finalProps = entityType ? { ...renderedProps, entity: storeData } : renderedProps;
|
|
35016
35069
|
return /* @__PURE__ */ jsx(
|
|
35017
35070
|
Box,
|
|
35018
35071
|
{
|
|
35019
35072
|
className: "slot-content",
|
|
35020
35073
|
"data-pattern": content.pattern,
|
|
35021
35074
|
"data-id": content.id,
|
|
35022
|
-
children: /* @__PURE__ */ jsx(PatternComponent, { ...
|
|
35075
|
+
children: /* @__PURE__ */ jsx(PatternComponent, { ...finalProps, children: renderedChildren })
|
|
35023
35076
|
}
|
|
35024
35077
|
);
|
|
35025
35078
|
}
|
|
@@ -37574,13 +37627,13 @@ function clearEntities() {
|
|
|
37574
37627
|
entities = /* @__PURE__ */ new Map();
|
|
37575
37628
|
notify();
|
|
37576
37629
|
}
|
|
37577
|
-
function
|
|
37630
|
+
function getSnapshot3() {
|
|
37578
37631
|
return entities;
|
|
37579
37632
|
}
|
|
37580
37633
|
|
|
37581
37634
|
// hooks/useEntities.ts
|
|
37582
37635
|
function useEntities() {
|
|
37583
|
-
const entities2 = useSyncExternalStore(subscribe,
|
|
37636
|
+
const entities2 = useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
|
|
37584
37637
|
return {
|
|
37585
37638
|
entities: entities2,
|
|
37586
37639
|
getEntity,
|
|
@@ -37595,15 +37648,15 @@ function useEntities() {
|
|
|
37595
37648
|
};
|
|
37596
37649
|
}
|
|
37597
37650
|
function useEntity2(id) {
|
|
37598
|
-
const entities2 = useSyncExternalStore(subscribe,
|
|
37651
|
+
const entities2 = useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
|
|
37599
37652
|
return entities2.get(id);
|
|
37600
37653
|
}
|
|
37601
37654
|
function useEntitiesByType(type) {
|
|
37602
|
-
const entities2 = useSyncExternalStore(subscribe,
|
|
37655
|
+
const entities2 = useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
|
|
37603
37656
|
return [...entities2.values()].filter((e) => e.type === type);
|
|
37604
37657
|
}
|
|
37605
37658
|
function useSingletonEntity(type) {
|
|
37606
|
-
const entities2 = useSyncExternalStore(subscribe,
|
|
37659
|
+
const entities2 = useSyncExternalStore(subscribe, getSnapshot3, getSnapshot3);
|
|
37607
37660
|
return [...entities2.values()].find((e) => e.type === type);
|
|
37608
37661
|
}
|
|
37609
37662
|
function usePlayer() {
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
* @packageDocumentation
|
|
13
13
|
*/
|
|
14
14
|
import React, { type ReactNode } from 'react';
|
|
15
|
+
type StoreListener = () => void;
|
|
15
16
|
type WatchCallback = (oldData: unknown[], newData: unknown[]) => void;
|
|
17
|
+
export declare function subscribeToStore(listener: StoreListener): () => void;
|
|
16
18
|
/**
|
|
17
19
|
* Subscribe to an entity type's data reactively.
|
|
18
20
|
* Re-renders only when the data for this specific entity type changes.
|
|
@@ -12,6 +12,8 @@ export interface ServerResponseMeta {
|
|
|
12
12
|
success: boolean;
|
|
13
13
|
clientEffects: number;
|
|
14
14
|
dataEntities: Record<string, number>;
|
|
15
|
+
/** Raw entity data from server response (for EntityStore advancement) */
|
|
16
|
+
data?: Record<string, unknown[]>;
|
|
15
17
|
emittedEvents: string[];
|
|
16
18
|
error?: string;
|
|
17
19
|
}
|
|
@@ -18,6 +18,5 @@ export interface CreateClientEffectHandlersOptions {
|
|
|
18
18
|
slotSetter: SlotSetter;
|
|
19
19
|
navigate?: (path: string, params?: Record<string, unknown>) => void;
|
|
20
20
|
notify?: (message: string, type: 'success' | 'error' | 'warning' | 'info') => void;
|
|
21
|
-
enrichPattern?: (pattern: unknown) => unknown;
|
|
22
21
|
}
|
|
23
22
|
export declare function createClientEffectHandlers(options: CreateClientEffectHandlersOptions): EffectHandlers;
|
package/dist/runtime/index.cjs
CHANGED
|
@@ -685,7 +685,7 @@ typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_A
|
|
|
685
685
|
|
|
686
686
|
// runtime/createClientEffectHandlers.ts
|
|
687
687
|
function createClientEffectHandlers(options) {
|
|
688
|
-
const { eventBus, slotSetter, navigate, notify
|
|
688
|
+
const { eventBus, slotSetter, navigate, notify } = options;
|
|
689
689
|
return {
|
|
690
690
|
emit: (event, payload) => {
|
|
691
691
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -706,8 +706,7 @@ function createClientEffectHandlers(options) {
|
|
|
706
706
|
slotSetter.clearSlot(slot);
|
|
707
707
|
return;
|
|
708
708
|
}
|
|
709
|
-
|
|
710
|
-
slotSetter.addPattern(slot, enriched, props);
|
|
709
|
+
slotSetter.addPattern(slot, pattern, props);
|
|
711
710
|
},
|
|
712
711
|
navigate: navigate ?? ((path) => {
|
|
713
712
|
console.warn("[ClientEffectHandlers] No navigate handler, ignoring:", path);
|
|
@@ -2119,10 +2118,35 @@ function advance(entityType, data) {
|
|
|
2119
2118
|
function getSnapshot3(entityType) {
|
|
2120
2119
|
return store.get(entityType)?.data ?? [];
|
|
2121
2120
|
}
|
|
2121
|
+
function getVersion(entityType) {
|
|
2122
|
+
return store.get(entityType)?.version ?? 0;
|
|
2123
|
+
}
|
|
2124
|
+
function subscribeToStore(listener) {
|
|
2125
|
+
storeListeners.add(listener);
|
|
2126
|
+
return () => {
|
|
2127
|
+
storeListeners.delete(listener);
|
|
2128
|
+
};
|
|
2129
|
+
}
|
|
2130
|
+
function useEntityRef(entityType) {
|
|
2131
|
+
const versionRef = React118.useRef(0);
|
|
2132
|
+
const dataRef = React118.useRef([]);
|
|
2133
|
+
const getSnapshotStable = React118__namespace.default.useCallback(() => {
|
|
2134
|
+
const currentVersion = getVersion(entityType);
|
|
2135
|
+
if (currentVersion !== versionRef.current) {
|
|
2136
|
+
versionRef.current = currentVersion;
|
|
2137
|
+
dataRef.current = getSnapshot3(entityType);
|
|
2138
|
+
}
|
|
2139
|
+
return dataRef.current;
|
|
2140
|
+
}, [entityType]);
|
|
2141
|
+
return React118.useSyncExternalStore(subscribeToStore, getSnapshotStable, () => []);
|
|
2142
|
+
}
|
|
2122
2143
|
var EntityStoreContext = React118.createContext({
|
|
2123
2144
|
advance,
|
|
2124
2145
|
getSnapshot: getSnapshot3
|
|
2125
2146
|
});
|
|
2147
|
+
function useEntityStore() {
|
|
2148
|
+
return React118.useContext(EntityStoreContext);
|
|
2149
|
+
}
|
|
2126
2150
|
function EntityStoreProvider({ children }) {
|
|
2127
2151
|
return /* @__PURE__ */ jsxRuntime.jsx(EntityStoreContext.Provider, { value: { advance, getSnapshot: getSnapshot3 }, children });
|
|
2128
2152
|
}
|
|
@@ -32324,6 +32348,9 @@ function SlotContentRenderer({
|
|
|
32324
32348
|
content,
|
|
32325
32349
|
onDismiss
|
|
32326
32350
|
}) {
|
|
32351
|
+
const entityProp = content.props.entity;
|
|
32352
|
+
const entityType = typeof entityProp === "string" ? entityProp : "";
|
|
32353
|
+
const storeData = useEntityRef(entityType);
|
|
32327
32354
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
32328
32355
|
if (PatternComponent) {
|
|
32329
32356
|
const childrenConfig = content.props.children;
|
|
@@ -32331,13 +32358,14 @@ function SlotContentRenderer({
|
|
|
32331
32358
|
const renderedChildren = hasChildren ? renderPatternChildren(childrenConfig, onDismiss, content.id) : void 0;
|
|
32332
32359
|
const { children: _childrenConfig, ...restProps } = content.props;
|
|
32333
32360
|
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
32361
|
+
const finalProps = entityType ? { ...renderedProps, entity: storeData } : renderedProps;
|
|
32334
32362
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
32335
32363
|
Box,
|
|
32336
32364
|
{
|
|
32337
32365
|
className: "slot-content",
|
|
32338
32366
|
"data-pattern": content.pattern,
|
|
32339
32367
|
"data-id": content.id,
|
|
32340
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(PatternComponent, { ...
|
|
32368
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(PatternComponent, { ...finalProps, children: renderedChildren })
|
|
32341
32369
|
}
|
|
32342
32370
|
);
|
|
32343
32371
|
}
|
|
@@ -32620,41 +32648,6 @@ function OrbitalProvider({
|
|
|
32620
32648
|
);
|
|
32621
32649
|
}
|
|
32622
32650
|
OrbitalProvider.displayName = "OrbitalProvider";
|
|
32623
|
-
function enrichFromResponse(node, data) {
|
|
32624
|
-
if (!node || typeof node !== "object") return node ?? {};
|
|
32625
|
-
let enriched = node;
|
|
32626
|
-
if (Array.isArray(enriched.children)) {
|
|
32627
|
-
enriched = {
|
|
32628
|
-
...enriched,
|
|
32629
|
-
children: enriched.children.map(
|
|
32630
|
-
(child) => {
|
|
32631
|
-
if (!child || typeof child !== "object") return child;
|
|
32632
|
-
return enrichFromResponse(child, data);
|
|
32633
|
-
}
|
|
32634
|
-
)
|
|
32635
|
-
};
|
|
32636
|
-
}
|
|
32637
|
-
const nodeType = enriched.type;
|
|
32638
|
-
if (nodeType && patterns.isEntityAwarePattern(nodeType) && typeof enriched.entity === "string") {
|
|
32639
|
-
const entityName = enriched.entity;
|
|
32640
|
-
const records = data[entityName];
|
|
32641
|
-
if (records && records.length > 0) {
|
|
32642
|
-
enriched = { ...enriched, entity: records };
|
|
32643
|
-
if (!enriched.fields && !enriched.columns) {
|
|
32644
|
-
const sample = records[0];
|
|
32645
|
-
if (sample && typeof sample === "object") {
|
|
32646
|
-
const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
|
|
32647
|
-
enriched = {
|
|
32648
|
-
...enriched,
|
|
32649
|
-
fields: keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" })),
|
|
32650
|
-
children: void 0
|
|
32651
|
-
};
|
|
32652
|
-
}
|
|
32653
|
-
}
|
|
32654
|
-
}
|
|
32655
|
-
}
|
|
32656
|
-
return enriched;
|
|
32657
|
-
}
|
|
32658
32651
|
var ServerBridgeContext = React118.createContext(null);
|
|
32659
32652
|
function useServerBridge() {
|
|
32660
32653
|
const ctx = React118.useContext(ServerBridgeContext);
|
|
@@ -32711,6 +32704,7 @@ function ServerBridgeProvider({
|
|
|
32711
32704
|
success: !!result.success,
|
|
32712
32705
|
clientEffects: result.clientEffects?.length ?? 0,
|
|
32713
32706
|
dataEntities,
|
|
32707
|
+
data: responseData,
|
|
32714
32708
|
emittedEvents: result.emittedEvents?.map((e) => e.event) ?? [],
|
|
32715
32709
|
error: result.error
|
|
32716
32710
|
};
|
|
@@ -32722,8 +32716,7 @@ function ServerBridgeProvider({
|
|
|
32722
32716
|
if (effectType === "render-ui") {
|
|
32723
32717
|
const slot = arr[1];
|
|
32724
32718
|
const pattern = arr[2];
|
|
32725
|
-
|
|
32726
|
-
effects.push({ type: "render-ui", slot, pattern: enriched });
|
|
32719
|
+
effects.push({ type: "render-ui", slot, pattern: pattern ?? void 0 });
|
|
32727
32720
|
} else if (effectType === "navigate") {
|
|
32728
32721
|
effects.push({ type: "navigate", route: arr[1], params: arr[2] });
|
|
32729
32722
|
} else if (effectType === "notify") {
|
|
@@ -32768,7 +32761,7 @@ function normalizeChild(child) {
|
|
|
32768
32761
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
32769
32762
|
};
|
|
32770
32763
|
}
|
|
32771
|
-
function SlotBridge(
|
|
32764
|
+
function SlotBridge() {
|
|
32772
32765
|
const slots = useSlots();
|
|
32773
32766
|
const { render, clear } = context.useUISlots();
|
|
32774
32767
|
React118.useEffect(() => {
|
|
@@ -32778,10 +32771,7 @@ function SlotBridge({ mockData }) {
|
|
|
32778
32771
|
continue;
|
|
32779
32772
|
}
|
|
32780
32773
|
const entry = slotState.patterns[slotState.patterns.length - 1];
|
|
32781
|
-
|
|
32782
|
-
if (mockData && Object.keys(mockData).length > 0) {
|
|
32783
|
-
patternRecord = enrichFromResponse(patternRecord, mockData);
|
|
32784
|
-
}
|
|
32774
|
+
const patternRecord = entry.pattern;
|
|
32785
32775
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
32786
32776
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
32787
32777
|
render({
|
|
@@ -32795,17 +32785,26 @@ function SlotBridge({ mockData }) {
|
|
|
32795
32785
|
sourceTrait: slotState.source?.trait
|
|
32796
32786
|
});
|
|
32797
32787
|
}
|
|
32798
|
-
}, [slots, render, clear
|
|
32788
|
+
}, [slots, render, clear]);
|
|
32799
32789
|
return null;
|
|
32800
32790
|
}
|
|
32801
32791
|
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate }) {
|
|
32802
32792
|
const slotsActions = useSlotsActions();
|
|
32803
32793
|
const bridge = useServerBridge();
|
|
32794
|
+
const entityStore = useEntityStore();
|
|
32804
32795
|
const onEventProcessed = React118.useCallback(async (event, payload) => {
|
|
32805
32796
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
32806
32797
|
for (const name of orbitalNames) {
|
|
32807
32798
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
32808
32799
|
recordServerResponse(name, event, meta);
|
|
32800
|
+
const responseData = meta?.data;
|
|
32801
|
+
if (responseData) {
|
|
32802
|
+
for (const [entityType, records] of Object.entries(responseData)) {
|
|
32803
|
+
if (Array.isArray(records)) {
|
|
32804
|
+
entityStore.advance(entityType, records);
|
|
32805
|
+
}
|
|
32806
|
+
}
|
|
32807
|
+
}
|
|
32809
32808
|
for (const eff of effects) {
|
|
32810
32809
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
32811
32810
|
slotsActions.setSlotPatterns(
|
|
@@ -32818,7 +32817,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate }) {
|
|
|
32818
32817
|
}
|
|
32819
32818
|
}
|
|
32820
32819
|
}
|
|
32821
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, slotsActions, onNavigate]);
|
|
32820
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, slotsActions, onNavigate, entityStore]);
|
|
32822
32821
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate } : { navigate: onNavigate };
|
|
32823
32822
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
32824
32823
|
const initSentRef = React118.useRef(false);
|
|
@@ -32857,6 +32856,14 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate }) {
|
|
|
32857
32856
|
effects: effectTraces,
|
|
32858
32857
|
timestamp: Date.now()
|
|
32859
32858
|
});
|
|
32859
|
+
const initResponseData = meta?.data;
|
|
32860
|
+
if (initResponseData) {
|
|
32861
|
+
for (const [entityType, records] of Object.entries(initResponseData)) {
|
|
32862
|
+
if (Array.isArray(records)) {
|
|
32863
|
+
entityStore.advance(entityType, records);
|
|
32864
|
+
}
|
|
32865
|
+
}
|
|
32866
|
+
}
|
|
32860
32867
|
for (const eff of effects) {
|
|
32861
32868
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
32862
32869
|
slotsActions.setSlotPatterns(
|
|
@@ -32897,9 +32904,19 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate }) {
|
|
|
32897
32904
|
if (!orbitals) return [];
|
|
32898
32905
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
32899
32906
|
}, [schema]);
|
|
32907
|
+
const entityStore = useEntityStore();
|
|
32908
|
+
React118.useEffect(() => {
|
|
32909
|
+
if (!serverUrl && mockData) {
|
|
32910
|
+
for (const [entityType, records] of Object.entries(mockData)) {
|
|
32911
|
+
if (Array.isArray(records)) {
|
|
32912
|
+
entityStore.advance(entityType, records);
|
|
32913
|
+
}
|
|
32914
|
+
}
|
|
32915
|
+
}
|
|
32916
|
+
}, [mockData, serverUrl, entityStore]);
|
|
32900
32917
|
const inner = /* @__PURE__ */ jsxRuntime.jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(SlotsProvider, { children: /* @__PURE__ */ jsxRuntime.jsxs(EntitySchemaProvider, { entities: Array.from(allEntities.values()), children: [
|
|
32901
32918
|
/* @__PURE__ */ jsxRuntime.jsx(TraitInitializer, { traits: allPageTraits, orbitalNames: serverUrl ? orbitalNames : void 0, onNavigate }),
|
|
32902
|
-
/* @__PURE__ */ jsxRuntime.jsx(SlotBridge, {
|
|
32919
|
+
/* @__PURE__ */ jsxRuntime.jsx(SlotBridge, {}),
|
|
32903
32920
|
/* @__PURE__ */ jsxRuntime.jsx(Box, { className: "min-h-full p-4", children: /* @__PURE__ */ jsxRuntime.jsx(UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) })
|
|
32904
32921
|
] }) }) });
|
|
32905
32922
|
if (serverUrl) {
|
|
@@ -32982,7 +32999,6 @@ exports.TraitContext = TraitContext;
|
|
|
32982
32999
|
exports.TraitProvider = TraitProvider;
|
|
32983
33000
|
exports.clearSchemaCache = clearSchemaCache;
|
|
32984
33001
|
exports.createClientEffectHandlers = createClientEffectHandlers;
|
|
32985
|
-
exports.enrichFromResponse = enrichFromResponse;
|
|
32986
33002
|
exports.useEntityDefinition = useEntityDefinition;
|
|
32987
33003
|
exports.useEntitySchema = useEntitySchema;
|
|
32988
33004
|
exports.useResolvedSchema = useResolvedSchema;
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -14,5 +14,4 @@ export { SlotsProvider, useSlots, useSlotContent, useSlotsActions, type SlotsSta
|
|
|
14
14
|
export { createClientEffectHandlers, type ClientEventBus, type SlotSetter, type CreateClientEffectHandlersOptions, } from './createClientEffectHandlers';
|
|
15
15
|
export { OrbPreview, type OrbPreviewProps } from './OrbPreview';
|
|
16
16
|
export { ServerBridgeProvider, useServerBridge, type ServerBridgeContextValue, type ServerClientEffect } from './ServerBridge';
|
|
17
|
-
export { enrichFromResponse } from './enrichFromResponse';
|
|
18
17
|
export type { ResolvedTraitBinding, ResolvedTrait, ResolvedEntity, ResolvedPage, ResolvedIR, } from './types';
|
package/dist/runtime/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React118 from 'react';
|
|
2
|
-
import React118__default, { createContext, useCallback, useState, useRef, useEffect, useLayoutEffect, lazy, useContext, useMemo, Suspense, useId } from 'react';
|
|
2
|
+
import React118__default, { createContext, useCallback, useState, useRef, useEffect, useLayoutEffect, lazy, useContext, useMemo, Suspense, useSyncExternalStore, useId } from 'react';
|
|
3
3
|
import { EventBusContext } from '@almadar/ui/providers';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
5
|
import '@tanstack/react-query';
|
|
@@ -12,7 +12,7 @@ import { UISlotProvider, useUISlots } from '@almadar/ui/context';
|
|
|
12
12
|
import * as LucideIcons from 'lucide-react';
|
|
13
13
|
import { Loader2, ChevronDown, X, ArrowRight, TrendingDown, TrendingUp, Check, Copy, AlertCircle, AlertTriangle, Info, CheckCircle, ChevronLeft, ChevronRight, FileWarning, Upload, Circle, Clock, CheckCircle2, Sun, Moon, ArrowUp, ArrowDown, MoreVertical, Minus, Star, XCircle, Play, RotateCcw, Pause, SkipForward, Eraser, Search, HelpCircle, ChevronUp, ArrowLeft, Plus, Image as Image$1, ZoomIn, Package, Menu as Menu$1, ZoomOut, Filter, FileQuestion, Inbox, FileText, Download, Printer, Bug, Send, MoreHorizontal, Settings, Bell, LogOut, Trash2, Zap, Sword, Move, Heart, Shield, Code, WrapText, Wrench, List, Calendar, Pencil, Eye, User, Tag, DollarSign } from 'lucide-react';
|
|
14
14
|
import { evaluate, createMinimalContext } from '@almadar/evaluator';
|
|
15
|
-
import {
|
|
15
|
+
import { getComponentForPattern as getComponentForPattern$1 } from '@almadar/patterns';
|
|
16
16
|
import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet';
|
|
17
17
|
import L from 'leaflet';
|
|
18
18
|
import 'leaflet/dist/leaflet.css';
|
|
@@ -655,7 +655,7 @@ typeof process !== "undefined" && process.env?.VITE_API_URL ? process.env.VITE_A
|
|
|
655
655
|
|
|
656
656
|
// runtime/createClientEffectHandlers.ts
|
|
657
657
|
function createClientEffectHandlers(options) {
|
|
658
|
-
const { eventBus, slotSetter, navigate, notify
|
|
658
|
+
const { eventBus, slotSetter, navigate, notify } = options;
|
|
659
659
|
return {
|
|
660
660
|
emit: (event, payload) => {
|
|
661
661
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -676,8 +676,7 @@ function createClientEffectHandlers(options) {
|
|
|
676
676
|
slotSetter.clearSlot(slot);
|
|
677
677
|
return;
|
|
678
678
|
}
|
|
679
|
-
|
|
680
|
-
slotSetter.addPattern(slot, enriched, props);
|
|
679
|
+
slotSetter.addPattern(slot, pattern, props);
|
|
681
680
|
},
|
|
682
681
|
navigate: navigate ?? ((path) => {
|
|
683
682
|
console.warn("[ClientEffectHandlers] No navigate handler, ignoring:", path);
|
|
@@ -2089,10 +2088,35 @@ function advance(entityType, data) {
|
|
|
2089
2088
|
function getSnapshot3(entityType) {
|
|
2090
2089
|
return store.get(entityType)?.data ?? [];
|
|
2091
2090
|
}
|
|
2091
|
+
function getVersion(entityType) {
|
|
2092
|
+
return store.get(entityType)?.version ?? 0;
|
|
2093
|
+
}
|
|
2094
|
+
function subscribeToStore(listener) {
|
|
2095
|
+
storeListeners.add(listener);
|
|
2096
|
+
return () => {
|
|
2097
|
+
storeListeners.delete(listener);
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
function useEntityRef(entityType) {
|
|
2101
|
+
const versionRef = useRef(0);
|
|
2102
|
+
const dataRef = useRef([]);
|
|
2103
|
+
const getSnapshotStable = React118__default.useCallback(() => {
|
|
2104
|
+
const currentVersion = getVersion(entityType);
|
|
2105
|
+
if (currentVersion !== versionRef.current) {
|
|
2106
|
+
versionRef.current = currentVersion;
|
|
2107
|
+
dataRef.current = getSnapshot3(entityType);
|
|
2108
|
+
}
|
|
2109
|
+
return dataRef.current;
|
|
2110
|
+
}, [entityType]);
|
|
2111
|
+
return useSyncExternalStore(subscribeToStore, getSnapshotStable, () => []);
|
|
2112
|
+
}
|
|
2092
2113
|
var EntityStoreContext = createContext({
|
|
2093
2114
|
advance,
|
|
2094
2115
|
getSnapshot: getSnapshot3
|
|
2095
2116
|
});
|
|
2117
|
+
function useEntityStore() {
|
|
2118
|
+
return useContext(EntityStoreContext);
|
|
2119
|
+
}
|
|
2096
2120
|
function EntityStoreProvider({ children }) {
|
|
2097
2121
|
return /* @__PURE__ */ jsx(EntityStoreContext.Provider, { value: { advance, getSnapshot: getSnapshot3 }, children });
|
|
2098
2122
|
}
|
|
@@ -32294,6 +32318,9 @@ function SlotContentRenderer({
|
|
|
32294
32318
|
content,
|
|
32295
32319
|
onDismiss
|
|
32296
32320
|
}) {
|
|
32321
|
+
const entityProp = content.props.entity;
|
|
32322
|
+
const entityType = typeof entityProp === "string" ? entityProp : "";
|
|
32323
|
+
const storeData = useEntityRef(entityType);
|
|
32297
32324
|
const PatternComponent = getComponentForPattern(content.pattern);
|
|
32298
32325
|
if (PatternComponent) {
|
|
32299
32326
|
const childrenConfig = content.props.children;
|
|
@@ -32301,13 +32328,14 @@ function SlotContentRenderer({
|
|
|
32301
32328
|
const renderedChildren = hasChildren ? renderPatternChildren(childrenConfig, onDismiss, content.id) : void 0;
|
|
32302
32329
|
const { children: _childrenConfig, ...restProps } = content.props;
|
|
32303
32330
|
const renderedProps = renderPatternProps(restProps, onDismiss);
|
|
32331
|
+
const finalProps = entityType ? { ...renderedProps, entity: storeData } : renderedProps;
|
|
32304
32332
|
return /* @__PURE__ */ jsx(
|
|
32305
32333
|
Box,
|
|
32306
32334
|
{
|
|
32307
32335
|
className: "slot-content",
|
|
32308
32336
|
"data-pattern": content.pattern,
|
|
32309
32337
|
"data-id": content.id,
|
|
32310
|
-
children: /* @__PURE__ */ jsx(PatternComponent, { ...
|
|
32338
|
+
children: /* @__PURE__ */ jsx(PatternComponent, { ...finalProps, children: renderedChildren })
|
|
32311
32339
|
}
|
|
32312
32340
|
);
|
|
32313
32341
|
}
|
|
@@ -32590,41 +32618,6 @@ function OrbitalProvider({
|
|
|
32590
32618
|
);
|
|
32591
32619
|
}
|
|
32592
32620
|
OrbitalProvider.displayName = "OrbitalProvider";
|
|
32593
|
-
function enrichFromResponse(node, data) {
|
|
32594
|
-
if (!node || typeof node !== "object") return node ?? {};
|
|
32595
|
-
let enriched = node;
|
|
32596
|
-
if (Array.isArray(enriched.children)) {
|
|
32597
|
-
enriched = {
|
|
32598
|
-
...enriched,
|
|
32599
|
-
children: enriched.children.map(
|
|
32600
|
-
(child) => {
|
|
32601
|
-
if (!child || typeof child !== "object") return child;
|
|
32602
|
-
return enrichFromResponse(child, data);
|
|
32603
|
-
}
|
|
32604
|
-
)
|
|
32605
|
-
};
|
|
32606
|
-
}
|
|
32607
|
-
const nodeType = enriched.type;
|
|
32608
|
-
if (nodeType && isEntityAwarePattern(nodeType) && typeof enriched.entity === "string") {
|
|
32609
|
-
const entityName = enriched.entity;
|
|
32610
|
-
const records = data[entityName];
|
|
32611
|
-
if (records && records.length > 0) {
|
|
32612
|
-
enriched = { ...enriched, entity: records };
|
|
32613
|
-
if (!enriched.fields && !enriched.columns) {
|
|
32614
|
-
const sample = records[0];
|
|
32615
|
-
if (sample && typeof sample === "object") {
|
|
32616
|
-
const keys = Object.keys(sample).filter((k) => k !== "id" && k !== "_id");
|
|
32617
|
-
enriched = {
|
|
32618
|
-
...enriched,
|
|
32619
|
-
fields: keys.map((k, i) => ({ name: k, variant: i === 0 ? "h4" : "body" })),
|
|
32620
|
-
children: void 0
|
|
32621
|
-
};
|
|
32622
|
-
}
|
|
32623
|
-
}
|
|
32624
|
-
}
|
|
32625
|
-
}
|
|
32626
|
-
return enriched;
|
|
32627
|
-
}
|
|
32628
32621
|
var ServerBridgeContext = createContext(null);
|
|
32629
32622
|
function useServerBridge() {
|
|
32630
32623
|
const ctx = useContext(ServerBridgeContext);
|
|
@@ -32681,6 +32674,7 @@ function ServerBridgeProvider({
|
|
|
32681
32674
|
success: !!result.success,
|
|
32682
32675
|
clientEffects: result.clientEffects?.length ?? 0,
|
|
32683
32676
|
dataEntities,
|
|
32677
|
+
data: responseData,
|
|
32684
32678
|
emittedEvents: result.emittedEvents?.map((e) => e.event) ?? [],
|
|
32685
32679
|
error: result.error
|
|
32686
32680
|
};
|
|
@@ -32692,8 +32686,7 @@ function ServerBridgeProvider({
|
|
|
32692
32686
|
if (effectType === "render-ui") {
|
|
32693
32687
|
const slot = arr[1];
|
|
32694
32688
|
const pattern = arr[2];
|
|
32695
|
-
|
|
32696
|
-
effects.push({ type: "render-ui", slot, pattern: enriched });
|
|
32689
|
+
effects.push({ type: "render-ui", slot, pattern: pattern ?? void 0 });
|
|
32697
32690
|
} else if (effectType === "navigate") {
|
|
32698
32691
|
effects.push({ type: "navigate", route: arr[1], params: arr[2] });
|
|
32699
32692
|
} else if (effectType === "notify") {
|
|
@@ -32738,7 +32731,7 @@ function normalizeChild(child) {
|
|
|
32738
32731
|
props: { ...rest, ...normalizedChildren !== void 0 ? { children: normalizedChildren } : {} }
|
|
32739
32732
|
};
|
|
32740
32733
|
}
|
|
32741
|
-
function SlotBridge(
|
|
32734
|
+
function SlotBridge() {
|
|
32742
32735
|
const slots = useSlots();
|
|
32743
32736
|
const { render, clear } = useUISlots();
|
|
32744
32737
|
useEffect(() => {
|
|
@@ -32748,10 +32741,7 @@ function SlotBridge({ mockData }) {
|
|
|
32748
32741
|
continue;
|
|
32749
32742
|
}
|
|
32750
32743
|
const entry = slotState.patterns[slotState.patterns.length - 1];
|
|
32751
|
-
|
|
32752
|
-
if (mockData && Object.keys(mockData).length > 0) {
|
|
32753
|
-
patternRecord = enrichFromResponse(patternRecord, mockData);
|
|
32754
|
-
}
|
|
32744
|
+
const patternRecord = entry.pattern;
|
|
32755
32745
|
const { type: patternType, children, ...inlineProps } = patternRecord;
|
|
32756
32746
|
const normalizedChildren = Array.isArray(children) ? children.map((c) => normalizeChild(c)) : children;
|
|
32757
32747
|
render({
|
|
@@ -32765,17 +32755,26 @@ function SlotBridge({ mockData }) {
|
|
|
32765
32755
|
sourceTrait: slotState.source?.trait
|
|
32766
32756
|
});
|
|
32767
32757
|
}
|
|
32768
|
-
}, [slots, render, clear
|
|
32758
|
+
}, [slots, render, clear]);
|
|
32769
32759
|
return null;
|
|
32770
32760
|
}
|
|
32771
32761
|
function TraitInitializer({ traits: traits2, orbitalNames, onNavigate }) {
|
|
32772
32762
|
const slotsActions = useSlotsActions();
|
|
32773
32763
|
const bridge = useServerBridge();
|
|
32764
|
+
const entityStore = useEntityStore();
|
|
32774
32765
|
const onEventProcessed = useCallback(async (event, payload) => {
|
|
32775
32766
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
32776
32767
|
for (const name of orbitalNames) {
|
|
32777
32768
|
const { effects, meta } = await bridge.sendEvent(name, event, payload);
|
|
32778
32769
|
recordServerResponse(name, event, meta);
|
|
32770
|
+
const responseData = meta?.data;
|
|
32771
|
+
if (responseData) {
|
|
32772
|
+
for (const [entityType, records] of Object.entries(responseData)) {
|
|
32773
|
+
if (Array.isArray(records)) {
|
|
32774
|
+
entityStore.advance(entityType, records);
|
|
32775
|
+
}
|
|
32776
|
+
}
|
|
32777
|
+
}
|
|
32779
32778
|
for (const eff of effects) {
|
|
32780
32779
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
32781
32780
|
slotsActions.setSlotPatterns(
|
|
@@ -32788,7 +32787,7 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate }) {
|
|
|
32788
32787
|
}
|
|
32789
32788
|
}
|
|
32790
32789
|
}
|
|
32791
|
-
}, [bridge.connected, bridge.sendEvent, orbitalNames, slotsActions, onNavigate]);
|
|
32790
|
+
}, [bridge.connected, bridge.sendEvent, orbitalNames, slotsActions, onNavigate, entityStore]);
|
|
32792
32791
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate } : { navigate: onNavigate };
|
|
32793
32792
|
const { sendEvent } = useTraitStateMachine(traits2, slotsActions, opts);
|
|
32794
32793
|
const initSentRef = useRef(false);
|
|
@@ -32827,6 +32826,14 @@ function TraitInitializer({ traits: traits2, orbitalNames, onNavigate }) {
|
|
|
32827
32826
|
effects: effectTraces,
|
|
32828
32827
|
timestamp: Date.now()
|
|
32829
32828
|
});
|
|
32829
|
+
const initResponseData = meta?.data;
|
|
32830
|
+
if (initResponseData) {
|
|
32831
|
+
for (const [entityType, records] of Object.entries(initResponseData)) {
|
|
32832
|
+
if (Array.isArray(records)) {
|
|
32833
|
+
entityStore.advance(entityType, records);
|
|
32834
|
+
}
|
|
32835
|
+
}
|
|
32836
|
+
}
|
|
32830
32837
|
for (const eff of effects) {
|
|
32831
32838
|
if (eff.type === "render-ui" && eff.slot && eff.pattern) {
|
|
32832
32839
|
slotsActions.setSlotPatterns(
|
|
@@ -32867,9 +32874,19 @@ function SchemaRunner({ schema, serverUrl, mockData, pageName, onNavigate }) {
|
|
|
32867
32874
|
if (!orbitals) return [];
|
|
32868
32875
|
return orbitals.filter((o) => typeof o.name === "string").map((o) => o.name);
|
|
32869
32876
|
}, [schema]);
|
|
32877
|
+
const entityStore = useEntityStore();
|
|
32878
|
+
useEffect(() => {
|
|
32879
|
+
if (!serverUrl && mockData) {
|
|
32880
|
+
for (const [entityType, records] of Object.entries(mockData)) {
|
|
32881
|
+
if (Array.isArray(records)) {
|
|
32882
|
+
entityStore.advance(entityType, records);
|
|
32883
|
+
}
|
|
32884
|
+
}
|
|
32885
|
+
}
|
|
32886
|
+
}, [mockData, serverUrl, entityStore]);
|
|
32870
32887
|
const inner = /* @__PURE__ */ jsx(VerificationProvider, { enabled: true, children: /* @__PURE__ */ jsx(SlotsProvider, { children: /* @__PURE__ */ jsxs(EntitySchemaProvider, { entities: Array.from(allEntities.values()), children: [
|
|
32871
32888
|
/* @__PURE__ */ jsx(TraitInitializer, { traits: allPageTraits, orbitalNames: serverUrl ? orbitalNames : void 0, onNavigate }),
|
|
32872
|
-
/* @__PURE__ */ jsx(SlotBridge, {
|
|
32889
|
+
/* @__PURE__ */ jsx(SlotBridge, {}),
|
|
32873
32890
|
/* @__PURE__ */ jsx(Box, { className: "min-h-full p-4", children: /* @__PURE__ */ jsx(UISlotRenderer, { includeHud: true, hudMode: "inline", includeFloating: true }) })
|
|
32874
32891
|
] }) }) });
|
|
32875
32892
|
if (serverUrl) {
|
|
@@ -32944,4 +32961,4 @@ function OrbPreview({
|
|
|
32944
32961
|
}
|
|
32945
32962
|
OrbPreview.displayName = "OrbPreview";
|
|
32946
32963
|
|
|
32947
|
-
export { EntitySchemaProvider, OrbPreview, ServerBridgeProvider, SlotsProvider, TraitContext, TraitProvider, clearSchemaCache, createClientEffectHandlers,
|
|
32964
|
+
export { EntitySchemaProvider, OrbPreview, ServerBridgeProvider, SlotsProvider, TraitContext, TraitProvider, clearSchemaCache, createClientEffectHandlers, useEntityDefinition, useEntitySchema, useResolvedSchema, useServerBridge, useSlotContent, useSlots, useSlotsActions, useTrait, useTraitContext, useTraitStateMachine };
|
package/package.json
CHANGED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* enrichFromResponse
|
|
3
|
-
*
|
|
4
|
-
* Walks a pattern tree from a server response and injects entity data
|
|
5
|
-
* into entity-aware patterns. Uses isEntityAwarePattern() from
|
|
6
|
-
* @almadar/patterns (registry-driven, not a hardcoded list).
|
|
7
|
-
*
|
|
8
|
-
* This is the single place where entity data meets UI patterns.
|
|
9
|
-
* Called by ServerBridge/ServerBridgeProvider when processing
|
|
10
|
-
* clientEffects from the server response.
|
|
11
|
-
*
|
|
12
|
-
* @packageDocumentation
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Enrich a pattern tree with entity data from a server response.
|
|
16
|
-
*
|
|
17
|
-
* @param node - Pattern config node (from server clientEffects)
|
|
18
|
-
* @param data - Entity records keyed by entity name (from server response.data)
|
|
19
|
-
* @returns Enriched pattern with entity arrays injected
|
|
20
|
-
*/
|
|
21
|
-
export declare function enrichFromResponse(node: Record<string, unknown> | null | undefined, data: Record<string, unknown[]>): Record<string, unknown>;
|