@almadar/ui 4.16.4 → 4.18.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.
@@ -19038,13 +19038,6 @@ var init_Pagination = __esm({
19038
19038
  const eventBus = useEventBus();
19039
19039
  const { t } = useTranslate();
19040
19040
  const [jumpToPage, setJumpToPage] = React127.useState("");
19041
- console.log("[Pagination] render", {
19042
- currentPage,
19043
- currentPageType: typeof currentPage,
19044
- totalPages,
19045
- totalPagesType: typeof totalPages,
19046
- pageChangeEvent
19047
- });
19048
19041
  const handlePageChange = (page) => {
19049
19042
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
19050
19043
  onPageChange(page);
@@ -51776,16 +51769,8 @@ init_EntitySchemaContext();
51776
51769
  init_traitRegistry();
51777
51770
  init_verificationRegistry();
51778
51771
  var crossTraitLog = createLogger("almadar:ui:cross-trait");
51779
- var reducerMirrorLog = createLogger("almadar:ui:reducer-mirror");
51780
51772
  var flushLog = createLogger("almadar:ui:slot-flush");
51781
51773
  var stateLog = createLogger("almadar:ui:state-transitions");
51782
- function readPayloadRows(payload) {
51783
- const data = payload?.["data"];
51784
- if (!Array.isArray(data)) return null;
51785
- return data.filter(
51786
- (v) => v !== null && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date)
51787
- );
51788
- }
51789
51774
  function toTraitDefinition(binding) {
51790
51775
  return {
51791
51776
  name: binding.trait.name,
@@ -51893,6 +51878,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
51893
51878
  traitStatesRef.current = traitStates;
51894
51879
  }, [traitStates]);
51895
51880
  const traitSnapshotDataRef = React127.useRef(/* @__PURE__ */ new Map());
51881
+ const traitFieldStatesRef = React127.useRef(/* @__PURE__ */ new Map());
51896
51882
  React127.useEffect(() => {
51897
51883
  const mgr = managerRef.current;
51898
51884
  const bindings = traitBindingsRef.current;
@@ -52178,73 +52164,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52178
52164
  notify: clientHandlers.notify
52179
52165
  };
52180
52166
  }
52181
- const writeFetchResultToSnap = (fetchedEntityType, fetchResult) => {
52182
- if (!fetchResult) {
52183
- reducerMirrorLog.info("write:skip-null", { traitName, fetchedEntityType });
52184
- return;
52185
- }
52186
- const snapNow = traitSnapshotDataRef.current.get(traitName);
52187
- if (!snapNow) {
52188
- reducerMirrorLog.info("write:skip-no-snap", { traitName, fetchedEntityType });
52189
- return;
52190
- }
52191
- const rows = Array.isArray(fetchResult.rows) ? fetchResult.rows : [fetchResult.rows];
52192
- snapNow.data[fetchedEntityType] = rows;
52193
- reducerMirrorLog.info("write:ok", {
52194
- traitName,
52195
- fetchedEntityType,
52196
- rowCount: rows.length,
52197
- firstRowKeys: rows.length > 0 ? Object.keys(rows[0]).join(",") : "",
52198
- firstRowJson: rows.length > 0 ? JSON.stringify(rows[0]).slice(0, 200) : ""
52199
- });
52200
- };
52201
- const baseFetch = handlers.fetch;
52202
- const baseRef = handlers.ref;
52203
- const baseDeref = handlers.deref;
52167
+ const baseSet = handlers.set;
52204
52168
  handlers = {
52205
52169
  ...handlers,
52206
- ...baseFetch ? {
52207
- fetch: async (entityType, options2) => {
52208
- const r2 = await baseFetch(entityType, options2);
52209
- writeFetchResultToSnap(entityType, r2);
52210
- return r2;
52211
- }
52212
- } : {},
52213
- ...baseRef ? {
52214
- ref: async (entityType, options2) => {
52215
- const r2 = await baseRef(entityType, options2);
52216
- writeFetchResultToSnap(entityType, r2);
52217
- return r2;
52170
+ set: async (targetId, field, value) => {
52171
+ let fieldState = traitFieldStatesRef.current.get(traitName);
52172
+ if (!fieldState) {
52173
+ fieldState = {};
52174
+ traitFieldStatesRef.current.set(traitName, fieldState);
52218
52175
  }
52219
- } : {},
52220
- ...baseDeref ? {
52221
- deref: async (entityType, options2) => {
52222
- const r2 = await baseDeref(entityType, options2);
52223
- writeFetchResultToSnap(entityType, r2);
52224
- return r2;
52225
- }
52226
- } : {}
52176
+ fieldState[field] = value;
52177
+ if (baseSet) await baseSet(targetId, field, value);
52178
+ }
52227
52179
  };
52228
- const entityFromPayload = payload ?? {};
52229
- const reducerSnap = traitSnapshotDataRef.current.get(traitName);
52230
- const persistedRows = linkedEntity ? reducerSnap?.data[linkedEntity] : void 0;
52231
- let entityForBinding = entityFromPayload;
52232
- if (persistedRows && persistedRows.length > 0) {
52233
- const hybrid = Object.assign(
52234
- [...persistedRows],
52235
- persistedRows[0]
52236
- );
52237
- entityForBinding = hybrid;
52238
- }
52239
- reducerMirrorLog.info("read:bindingCtx", {
52240
- traitName,
52241
- linkedEntity,
52242
- eventKey: normalizedEvent,
52243
- snapDataKeys: reducerSnap ? Object.keys(reducerSnap.data).join(",") : "<no-snap>",
52244
- persistedRowCount: persistedRows?.length ?? 0,
52245
- source: persistedRows && persistedRows.length > 0 ? "reducer-mirror" : "payload",
52246
- entityJson: JSON.stringify(entityForBinding).slice(0, 200)
52247
- });
52180
+ const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
52248
52181
  const bindingCtx = {
52249
52182
  entity: entityForBinding,
52250
52183
  payload: payload || {},
@@ -52436,12 +52369,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52436
52369
  for (const transition of binding.trait.transitions) {
52437
52370
  allEvents.add(transition.event);
52438
52371
  }
52439
- reducerMirrorLog.info("binding:transitions", {
52440
- traitName: binding.trait.name,
52441
- linkedEntity: binding.linkedEntity,
52442
- transitions: binding.trait.transitions.map((t) => `${t.from}->${t.to}/${t.event}`).join(","),
52443
- events: binding.trait.events.map((e) => e.key).join(",")
52444
- });
52445
52372
  }
52446
52373
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
52447
52374
  const unsubscribes = [];
@@ -52456,27 +52383,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52456
52383
  }
52457
52384
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
52458
52385
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
52459
- const selfLinkedEntity = binding.linkedEntity;
52460
52386
  const unsub = eventBus.on(selfBusKey, (event) => {
52461
- if (event.source && event.source.fromBridge) {
52387
+ if (event.source && event.source.dispatched) {
52462
52388
  crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
52463
52389
  return;
52464
52390
  }
52465
- if (selfLinkedEntity) {
52466
- const rowsFromPayload = readPayloadRows(event.payload);
52467
- if (rowsFromPayload !== null) {
52468
- const snapNow = traitSnapshotDataRef.current.get(traitName);
52469
- if (snapNow) {
52470
- snapNow.data[selfLinkedEntity] = rowsFromPayload;
52471
- reducerMirrorLog.info("write:self-emit", {
52472
- traitName,
52473
- eventKey,
52474
- linkedEntity: selfLinkedEntity,
52475
- rowCount: rowsFromPayload.length
52476
- });
52477
- }
52478
- }
52479
- }
52480
52391
  crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
52481
52392
  enqueueAndDrain(eventKey, event.payload);
52482
52393
  });
package/dist/avl/index.js CHANGED
@@ -18992,13 +18992,6 @@ var init_Pagination = __esm({
18992
18992
  const eventBus = useEventBus();
18993
18993
  const { t } = useTranslate();
18994
18994
  const [jumpToPage, setJumpToPage] = useState("");
18995
- console.log("[Pagination] render", {
18996
- currentPage,
18997
- currentPageType: typeof currentPage,
18998
- totalPages,
18999
- totalPagesType: typeof totalPages,
19000
- pageChangeEvent
19001
- });
19002
18995
  const handlePageChange = (page) => {
19003
18996
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
19004
18997
  onPageChange(page);
@@ -51730,16 +51723,8 @@ init_EntitySchemaContext();
51730
51723
  init_traitRegistry();
51731
51724
  init_verificationRegistry();
51732
51725
  var crossTraitLog = createLogger("almadar:ui:cross-trait");
51733
- var reducerMirrorLog = createLogger("almadar:ui:reducer-mirror");
51734
51726
  var flushLog = createLogger("almadar:ui:slot-flush");
51735
51727
  var stateLog = createLogger("almadar:ui:state-transitions");
51736
- function readPayloadRows(payload) {
51737
- const data = payload?.["data"];
51738
- if (!Array.isArray(data)) return null;
51739
- return data.filter(
51740
- (v) => v !== null && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date)
51741
- );
51742
- }
51743
51728
  function toTraitDefinition(binding) {
51744
51729
  return {
51745
51730
  name: binding.trait.name,
@@ -51847,6 +51832,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
51847
51832
  traitStatesRef.current = traitStates;
51848
51833
  }, [traitStates]);
51849
51834
  const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
51835
+ const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
51850
51836
  useEffect(() => {
51851
51837
  const mgr = managerRef.current;
51852
51838
  const bindings = traitBindingsRef.current;
@@ -52132,73 +52118,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52132
52118
  notify: clientHandlers.notify
52133
52119
  };
52134
52120
  }
52135
- const writeFetchResultToSnap = (fetchedEntityType, fetchResult) => {
52136
- if (!fetchResult) {
52137
- reducerMirrorLog.info("write:skip-null", { traitName, fetchedEntityType });
52138
- return;
52139
- }
52140
- const snapNow = traitSnapshotDataRef.current.get(traitName);
52141
- if (!snapNow) {
52142
- reducerMirrorLog.info("write:skip-no-snap", { traitName, fetchedEntityType });
52143
- return;
52144
- }
52145
- const rows = Array.isArray(fetchResult.rows) ? fetchResult.rows : [fetchResult.rows];
52146
- snapNow.data[fetchedEntityType] = rows;
52147
- reducerMirrorLog.info("write:ok", {
52148
- traitName,
52149
- fetchedEntityType,
52150
- rowCount: rows.length,
52151
- firstRowKeys: rows.length > 0 ? Object.keys(rows[0]).join(",") : "",
52152
- firstRowJson: rows.length > 0 ? JSON.stringify(rows[0]).slice(0, 200) : ""
52153
- });
52154
- };
52155
- const baseFetch = handlers.fetch;
52156
- const baseRef = handlers.ref;
52157
- const baseDeref = handlers.deref;
52121
+ const baseSet = handlers.set;
52158
52122
  handlers = {
52159
52123
  ...handlers,
52160
- ...baseFetch ? {
52161
- fetch: async (entityType, options2) => {
52162
- const r2 = await baseFetch(entityType, options2);
52163
- writeFetchResultToSnap(entityType, r2);
52164
- return r2;
52165
- }
52166
- } : {},
52167
- ...baseRef ? {
52168
- ref: async (entityType, options2) => {
52169
- const r2 = await baseRef(entityType, options2);
52170
- writeFetchResultToSnap(entityType, r2);
52171
- return r2;
52124
+ set: async (targetId, field, value) => {
52125
+ let fieldState = traitFieldStatesRef.current.get(traitName);
52126
+ if (!fieldState) {
52127
+ fieldState = {};
52128
+ traitFieldStatesRef.current.set(traitName, fieldState);
52172
52129
  }
52173
- } : {},
52174
- ...baseDeref ? {
52175
- deref: async (entityType, options2) => {
52176
- const r2 = await baseDeref(entityType, options2);
52177
- writeFetchResultToSnap(entityType, r2);
52178
- return r2;
52179
- }
52180
- } : {}
52130
+ fieldState[field] = value;
52131
+ if (baseSet) await baseSet(targetId, field, value);
52132
+ }
52181
52133
  };
52182
- const entityFromPayload = payload ?? {};
52183
- const reducerSnap = traitSnapshotDataRef.current.get(traitName);
52184
- const persistedRows = linkedEntity ? reducerSnap?.data[linkedEntity] : void 0;
52185
- let entityForBinding = entityFromPayload;
52186
- if (persistedRows && persistedRows.length > 0) {
52187
- const hybrid = Object.assign(
52188
- [...persistedRows],
52189
- persistedRows[0]
52190
- );
52191
- entityForBinding = hybrid;
52192
- }
52193
- reducerMirrorLog.info("read:bindingCtx", {
52194
- traitName,
52195
- linkedEntity,
52196
- eventKey: normalizedEvent,
52197
- snapDataKeys: reducerSnap ? Object.keys(reducerSnap.data).join(",") : "<no-snap>",
52198
- persistedRowCount: persistedRows?.length ?? 0,
52199
- source: persistedRows && persistedRows.length > 0 ? "reducer-mirror" : "payload",
52200
- entityJson: JSON.stringify(entityForBinding).slice(0, 200)
52201
- });
52134
+ const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
52202
52135
  const bindingCtx = {
52203
52136
  entity: entityForBinding,
52204
52137
  payload: payload || {},
@@ -52390,12 +52323,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52390
52323
  for (const transition of binding.trait.transitions) {
52391
52324
  allEvents.add(transition.event);
52392
52325
  }
52393
- reducerMirrorLog.info("binding:transitions", {
52394
- traitName: binding.trait.name,
52395
- linkedEntity: binding.linkedEntity,
52396
- transitions: binding.trait.transitions.map((t) => `${t.from}->${t.to}/${t.event}`).join(","),
52397
- events: binding.trait.events.map((e) => e.key).join(",")
52398
- });
52399
52326
  }
52400
52327
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
52401
52328
  const unsubscribes = [];
@@ -52410,27 +52337,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
52410
52337
  }
52411
52338
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
52412
52339
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
52413
- const selfLinkedEntity = binding.linkedEntity;
52414
52340
  const unsub = eventBus.on(selfBusKey, (event) => {
52415
- if (event.source && event.source.fromBridge) {
52341
+ if (event.source && event.source.dispatched) {
52416
52342
  crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
52417
52343
  return;
52418
52344
  }
52419
- if (selfLinkedEntity) {
52420
- const rowsFromPayload = readPayloadRows(event.payload);
52421
- if (rowsFromPayload !== null) {
52422
- const snapNow = traitSnapshotDataRef.current.get(traitName);
52423
- if (snapNow) {
52424
- snapNow.data[selfLinkedEntity] = rowsFromPayload;
52425
- reducerMirrorLog.info("write:self-emit", {
52426
- traitName,
52427
- eventKey,
52428
- linkedEntity: selfLinkedEntity,
52429
- rowCount: rowsFromPayload.length
52430
- });
52431
- }
52432
- }
52433
- }
52434
52345
  crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
52435
52346
  enqueueAndDrain(eventKey, event.payload);
52436
52347
  });
@@ -14235,13 +14235,6 @@ var init_Pagination = __esm({
14235
14235
  const eventBus = useEventBus();
14236
14236
  const { t } = useTranslate();
14237
14237
  const [jumpToPage, setJumpToPage] = React110.useState("");
14238
- console.log("[Pagination] render", {
14239
- currentPage,
14240
- currentPageType: typeof currentPage,
14241
- totalPages,
14242
- totalPagesType: typeof totalPages,
14243
- pageChangeEvent
14244
- });
14245
14238
  const handlePageChange = (page) => {
14246
14239
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
14247
14240
  onPageChange(page);
@@ -41263,7 +41256,7 @@ function useUIEvents(dispatch, traitName, validEvents, eventBusInstance) {
41263
41256
  const unsubscribes = [];
41264
41257
  for (const smEvent of stableValidEvents) {
41265
41258
  const handler = (event) => {
41266
- if (event.source && event.source.fromBridge) {
41259
+ if (event.source && event.source.dispatched) {
41267
41260
  return;
41268
41261
  }
41269
41262
  dispatch(smEvent, event.payload);
@@ -14190,13 +14190,6 @@ var init_Pagination = __esm({
14190
14190
  const eventBus = useEventBus();
14191
14191
  const { t } = useTranslate();
14192
14192
  const [jumpToPage, setJumpToPage] = useState("");
14193
- console.log("[Pagination] render", {
14194
- currentPage,
14195
- currentPageType: typeof currentPage,
14196
- totalPages,
14197
- totalPagesType: typeof totalPages,
14198
- pageChangeEvent
14199
- });
14200
14193
  const handlePageChange = (page) => {
14201
14194
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
14202
14195
  onPageChange(page);
@@ -41218,7 +41211,7 @@ function useUIEvents(dispatch, traitName, validEvents, eventBusInstance) {
41218
41211
  const unsubscribes = [];
41219
41212
  for (const smEvent of stableValidEvents) {
41220
41213
  const handler = (event) => {
41221
- if (event.source && event.source.fromBridge) {
41214
+ if (event.source && event.source.dispatched) {
41222
41215
  return;
41223
41216
  }
41224
41217
  dispatch(smEvent, event.payload);
@@ -1399,7 +1399,7 @@ function useUIEvents(dispatch, traitName, validEvents, eventBusInstance) {
1399
1399
  const unsubscribes = [];
1400
1400
  for (const smEvent of stableValidEvents) {
1401
1401
  const handler = (event) => {
1402
- if (event.source && event.source.fromBridge) {
1402
+ if (event.source && event.source.dispatched) {
1403
1403
  return;
1404
1404
  }
1405
1405
  dispatch(smEvent, event.payload);
@@ -1397,7 +1397,7 @@ function useUIEvents(dispatch, traitName, validEvents, eventBusInstance) {
1397
1397
  const unsubscribes = [];
1398
1398
  for (const smEvent of stableValidEvents) {
1399
1399
  const handler = (event) => {
1400
- if (event.source && event.source.fromBridge) {
1400
+ if (event.source && event.source.dispatched) {
1401
1401
  return;
1402
1402
  }
1403
1403
  dispatch(smEvent, event.payload);
@@ -15789,13 +15789,6 @@ var init_Pagination = __esm({
15789
15789
  const eventBus = useEventBus();
15790
15790
  const { t } = useTranslate();
15791
15791
  const [jumpToPage, setJumpToPage] = React115.useState("");
15792
- console.log("[Pagination] render", {
15793
- currentPage,
15794
- currentPageType: typeof currentPage,
15795
- totalPages,
15796
- totalPagesType: typeof totalPages,
15797
- pageChangeEvent
15798
- });
15799
15792
  const handlePageChange = (page) => {
15800
15793
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
15801
15794
  onPageChange(page);
@@ -15744,13 +15744,6 @@ var init_Pagination = __esm({
15744
15744
  const eventBus = useEventBus();
15745
15745
  const { t } = useTranslate();
15746
15746
  const [jumpToPage, setJumpToPage] = useState("");
15747
- console.log("[Pagination] render", {
15748
- currentPage,
15749
- currentPageType: typeof currentPage,
15750
- totalPages,
15751
- totalPagesType: typeof totalPages,
15752
- pageChangeEvent
15753
- });
15754
15747
  const handlePageChange = (page) => {
15755
15748
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
15756
15749
  onPageChange(page);
@@ -15579,13 +15579,6 @@ var init_Pagination = __esm({
15579
15579
  const eventBus = useEventBus();
15580
15580
  const { t } = useTranslate();
15581
15581
  const [jumpToPage, setJumpToPage] = React113.useState("");
15582
- console.log("[Pagination] render", {
15583
- currentPage,
15584
- currentPageType: typeof currentPage,
15585
- totalPages,
15586
- totalPagesType: typeof totalPages,
15587
- pageChangeEvent
15588
- });
15589
15582
  const handlePageChange = (page) => {
15590
15583
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
15591
15584
  onPageChange(page);
@@ -38303,16 +38296,8 @@ init_EntitySchemaContext();
38303
38296
  init_traitRegistry();
38304
38297
  init_verificationRegistry();
38305
38298
  var crossTraitLog = createLogger("almadar:ui:cross-trait");
38306
- var reducerMirrorLog = createLogger("almadar:ui:reducer-mirror");
38307
38299
  var flushLog = createLogger("almadar:ui:slot-flush");
38308
38300
  var stateLog = createLogger("almadar:ui:state-transitions");
38309
- function readPayloadRows(payload) {
38310
- const data = payload?.["data"];
38311
- if (!Array.isArray(data)) return null;
38312
- return data.filter(
38313
- (v) => v !== null && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date)
38314
- );
38315
- }
38316
38301
  function toTraitDefinition(binding) {
38317
38302
  return {
38318
38303
  name: binding.trait.name,
@@ -38420,6 +38405,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38420
38405
  traitStatesRef.current = traitStates;
38421
38406
  }, [traitStates]);
38422
38407
  const traitSnapshotDataRef = React113.useRef(/* @__PURE__ */ new Map());
38408
+ const traitFieldStatesRef = React113.useRef(/* @__PURE__ */ new Map());
38423
38409
  React113.useEffect(() => {
38424
38410
  const mgr = managerRef.current;
38425
38411
  const bindings = traitBindingsRef.current;
@@ -38705,73 +38691,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38705
38691
  notify: clientHandlers.notify
38706
38692
  };
38707
38693
  }
38708
- const writeFetchResultToSnap = (fetchedEntityType, fetchResult) => {
38709
- if (!fetchResult) {
38710
- reducerMirrorLog.info("write:skip-null", { traitName, fetchedEntityType });
38711
- return;
38712
- }
38713
- const snapNow = traitSnapshotDataRef.current.get(traitName);
38714
- if (!snapNow) {
38715
- reducerMirrorLog.info("write:skip-no-snap", { traitName, fetchedEntityType });
38716
- return;
38717
- }
38718
- const rows = Array.isArray(fetchResult.rows) ? fetchResult.rows : [fetchResult.rows];
38719
- snapNow.data[fetchedEntityType] = rows;
38720
- reducerMirrorLog.info("write:ok", {
38721
- traitName,
38722
- fetchedEntityType,
38723
- rowCount: rows.length,
38724
- firstRowKeys: rows.length > 0 ? Object.keys(rows[0]).join(",") : "",
38725
- firstRowJson: rows.length > 0 ? JSON.stringify(rows[0]).slice(0, 200) : ""
38726
- });
38727
- };
38728
- const baseFetch = handlers.fetch;
38729
- const baseRef = handlers.ref;
38730
- const baseDeref = handlers.deref;
38694
+ const baseSet = handlers.set;
38731
38695
  handlers = {
38732
38696
  ...handlers,
38733
- ...baseFetch ? {
38734
- fetch: async (entityType, options2) => {
38735
- const r = await baseFetch(entityType, options2);
38736
- writeFetchResultToSnap(entityType, r);
38737
- return r;
38738
- }
38739
- } : {},
38740
- ...baseRef ? {
38741
- ref: async (entityType, options2) => {
38742
- const r = await baseRef(entityType, options2);
38743
- writeFetchResultToSnap(entityType, r);
38744
- return r;
38697
+ set: async (targetId, field, value) => {
38698
+ let fieldState = traitFieldStatesRef.current.get(traitName);
38699
+ if (!fieldState) {
38700
+ fieldState = {};
38701
+ traitFieldStatesRef.current.set(traitName, fieldState);
38745
38702
  }
38746
- } : {},
38747
- ...baseDeref ? {
38748
- deref: async (entityType, options2) => {
38749
- const r = await baseDeref(entityType, options2);
38750
- writeFetchResultToSnap(entityType, r);
38751
- return r;
38752
- }
38753
- } : {}
38703
+ fieldState[field] = value;
38704
+ if (baseSet) await baseSet(targetId, field, value);
38705
+ }
38754
38706
  };
38755
- const entityFromPayload = payload ?? {};
38756
- const reducerSnap = traitSnapshotDataRef.current.get(traitName);
38757
- const persistedRows = linkedEntity ? reducerSnap?.data[linkedEntity] : void 0;
38758
- let entityForBinding = entityFromPayload;
38759
- if (persistedRows && persistedRows.length > 0) {
38760
- const hybrid = Object.assign(
38761
- [...persistedRows],
38762
- persistedRows[0]
38763
- );
38764
- entityForBinding = hybrid;
38765
- }
38766
- reducerMirrorLog.info("read:bindingCtx", {
38767
- traitName,
38768
- linkedEntity,
38769
- eventKey: normalizedEvent,
38770
- snapDataKeys: reducerSnap ? Object.keys(reducerSnap.data).join(",") : "<no-snap>",
38771
- persistedRowCount: persistedRows?.length ?? 0,
38772
- source: persistedRows && persistedRows.length > 0 ? "reducer-mirror" : "payload",
38773
- entityJson: JSON.stringify(entityForBinding).slice(0, 200)
38774
- });
38707
+ const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
38775
38708
  const bindingCtx = {
38776
38709
  entity: entityForBinding,
38777
38710
  payload: payload || {},
@@ -38963,12 +38896,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38963
38896
  for (const transition of binding.trait.transitions) {
38964
38897
  allEvents.add(transition.event);
38965
38898
  }
38966
- reducerMirrorLog.info("binding:transitions", {
38967
- traitName: binding.trait.name,
38968
- linkedEntity: binding.linkedEntity,
38969
- transitions: binding.trait.transitions.map((t) => `${t.from}->${t.to}/${t.event}`).join(","),
38970
- events: binding.trait.events.map((e) => e.key).join(",")
38971
- });
38972
38899
  }
38973
38900
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
38974
38901
  const unsubscribes = [];
@@ -38983,27 +38910,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38983
38910
  }
38984
38911
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
38985
38912
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
38986
- const selfLinkedEntity = binding.linkedEntity;
38987
38913
  const unsub = eventBus.on(selfBusKey, (event) => {
38988
- if (event.source && event.source.fromBridge) {
38914
+ if (event.source && event.source.dispatched) {
38989
38915
  crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
38990
38916
  return;
38991
38917
  }
38992
- if (selfLinkedEntity) {
38993
- const rowsFromPayload = readPayloadRows(event.payload);
38994
- if (rowsFromPayload !== null) {
38995
- const snapNow = traitSnapshotDataRef.current.get(traitName);
38996
- if (snapNow) {
38997
- snapNow.data[selfLinkedEntity] = rowsFromPayload;
38998
- reducerMirrorLog.info("write:self-emit", {
38999
- traitName,
39000
- eventKey,
39001
- linkedEntity: selfLinkedEntity,
39002
- rowCount: rowsFromPayload.length
39003
- });
39004
- }
39005
- }
39006
- }
39007
38918
  crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
39008
38919
  enqueueAndDrain(eventKey, event.payload);
39009
38920
  });
@@ -15534,13 +15534,6 @@ var init_Pagination = __esm({
15534
15534
  const eventBus = useEventBus();
15535
15535
  const { t } = useTranslate();
15536
15536
  const [jumpToPage, setJumpToPage] = useState("");
15537
- console.log("[Pagination] render", {
15538
- currentPage,
15539
- currentPageType: typeof currentPage,
15540
- totalPages,
15541
- totalPagesType: typeof totalPages,
15542
- pageChangeEvent
15543
- });
15544
15537
  const handlePageChange = (page) => {
15545
15538
  if (pageChangeEvent) eventBus.emit(`UI:${pageChangeEvent}`, { page });
15546
15539
  onPageChange(page);
@@ -38258,16 +38251,8 @@ init_EntitySchemaContext();
38258
38251
  init_traitRegistry();
38259
38252
  init_verificationRegistry();
38260
38253
  var crossTraitLog = createLogger("almadar:ui:cross-trait");
38261
- var reducerMirrorLog = createLogger("almadar:ui:reducer-mirror");
38262
38254
  var flushLog = createLogger("almadar:ui:slot-flush");
38263
38255
  var stateLog = createLogger("almadar:ui:state-transitions");
38264
- function readPayloadRows(payload) {
38265
- const data = payload?.["data"];
38266
- if (!Array.isArray(data)) return null;
38267
- return data.filter(
38268
- (v) => v !== null && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date)
38269
- );
38270
- }
38271
38256
  function toTraitDefinition(binding) {
38272
38257
  return {
38273
38258
  name: binding.trait.name,
@@ -38375,6 +38360,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38375
38360
  traitStatesRef.current = traitStates;
38376
38361
  }, [traitStates]);
38377
38362
  const traitSnapshotDataRef = useRef(/* @__PURE__ */ new Map());
38363
+ const traitFieldStatesRef = useRef(/* @__PURE__ */ new Map());
38378
38364
  useEffect(() => {
38379
38365
  const mgr = managerRef.current;
38380
38366
  const bindings = traitBindingsRef.current;
@@ -38660,73 +38646,20 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38660
38646
  notify: clientHandlers.notify
38661
38647
  };
38662
38648
  }
38663
- const writeFetchResultToSnap = (fetchedEntityType, fetchResult) => {
38664
- if (!fetchResult) {
38665
- reducerMirrorLog.info("write:skip-null", { traitName, fetchedEntityType });
38666
- return;
38667
- }
38668
- const snapNow = traitSnapshotDataRef.current.get(traitName);
38669
- if (!snapNow) {
38670
- reducerMirrorLog.info("write:skip-no-snap", { traitName, fetchedEntityType });
38671
- return;
38672
- }
38673
- const rows = Array.isArray(fetchResult.rows) ? fetchResult.rows : [fetchResult.rows];
38674
- snapNow.data[fetchedEntityType] = rows;
38675
- reducerMirrorLog.info("write:ok", {
38676
- traitName,
38677
- fetchedEntityType,
38678
- rowCount: rows.length,
38679
- firstRowKeys: rows.length > 0 ? Object.keys(rows[0]).join(",") : "",
38680
- firstRowJson: rows.length > 0 ? JSON.stringify(rows[0]).slice(0, 200) : ""
38681
- });
38682
- };
38683
- const baseFetch = handlers.fetch;
38684
- const baseRef = handlers.ref;
38685
- const baseDeref = handlers.deref;
38649
+ const baseSet = handlers.set;
38686
38650
  handlers = {
38687
38651
  ...handlers,
38688
- ...baseFetch ? {
38689
- fetch: async (entityType, options2) => {
38690
- const r = await baseFetch(entityType, options2);
38691
- writeFetchResultToSnap(entityType, r);
38692
- return r;
38693
- }
38694
- } : {},
38695
- ...baseRef ? {
38696
- ref: async (entityType, options2) => {
38697
- const r = await baseRef(entityType, options2);
38698
- writeFetchResultToSnap(entityType, r);
38699
- return r;
38652
+ set: async (targetId, field, value) => {
38653
+ let fieldState = traitFieldStatesRef.current.get(traitName);
38654
+ if (!fieldState) {
38655
+ fieldState = {};
38656
+ traitFieldStatesRef.current.set(traitName, fieldState);
38700
38657
  }
38701
- } : {},
38702
- ...baseDeref ? {
38703
- deref: async (entityType, options2) => {
38704
- const r = await baseDeref(entityType, options2);
38705
- writeFetchResultToSnap(entityType, r);
38706
- return r;
38707
- }
38708
- } : {}
38658
+ fieldState[field] = value;
38659
+ if (baseSet) await baseSet(targetId, field, value);
38660
+ }
38709
38661
  };
38710
- const entityFromPayload = payload ?? {};
38711
- const reducerSnap = traitSnapshotDataRef.current.get(traitName);
38712
- const persistedRows = linkedEntity ? reducerSnap?.data[linkedEntity] : void 0;
38713
- let entityForBinding = entityFromPayload;
38714
- if (persistedRows && persistedRows.length > 0) {
38715
- const hybrid = Object.assign(
38716
- [...persistedRows],
38717
- persistedRows[0]
38718
- );
38719
- entityForBinding = hybrid;
38720
- }
38721
- reducerMirrorLog.info("read:bindingCtx", {
38722
- traitName,
38723
- linkedEntity,
38724
- eventKey: normalizedEvent,
38725
- snapDataKeys: reducerSnap ? Object.keys(reducerSnap.data).join(",") : "<no-snap>",
38726
- persistedRowCount: persistedRows?.length ?? 0,
38727
- source: persistedRows && persistedRows.length > 0 ? "reducer-mirror" : "payload",
38728
- entityJson: JSON.stringify(entityForBinding).slice(0, 200)
38729
- });
38662
+ const entityForBinding = traitFieldStatesRef.current.get(traitName) ?? {};
38730
38663
  const bindingCtx = {
38731
38664
  entity: entityForBinding,
38732
38665
  payload: payload || {},
@@ -38918,12 +38851,6 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38918
38851
  for (const transition of binding.trait.transitions) {
38919
38852
  allEvents.add(transition.event);
38920
38853
  }
38921
- reducerMirrorLog.info("binding:transitions", {
38922
- traitName: binding.trait.name,
38923
- linkedEntity: binding.linkedEntity,
38924
- transitions: binding.trait.transitions.map((t) => `${t.from}->${t.to}/${t.event}`).join(","),
38925
- events: binding.trait.events.map((e) => e.key).join(",")
38926
- });
38927
38854
  }
38928
38855
  console.log("[TraitStateMachine] Subscribing to events:", Array.from(allEvents));
38929
38856
  const unsubscribes = [];
@@ -38938,27 +38865,11 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
38938
38865
  }
38939
38866
  const selfBusKey = `UI:${orbitalName}.${traitName}.${eventKey}`;
38940
38867
  crossTraitLog.debug("self:subscribe", { traitName, busKey: selfBusKey, eventKey });
38941
- const selfLinkedEntity = binding.linkedEntity;
38942
38868
  const unsub = eventBus.on(selfBusKey, (event) => {
38943
- if (event.source && event.source.fromBridge) {
38869
+ if (event.source && event.source.dispatched) {
38944
38870
  crossTraitLog.debug("self:fire-skipped-bridge-echo", { traitName, busKey: selfBusKey, eventKey });
38945
38871
  return;
38946
38872
  }
38947
- if (selfLinkedEntity) {
38948
- const rowsFromPayload = readPayloadRows(event.payload);
38949
- if (rowsFromPayload !== null) {
38950
- const snapNow = traitSnapshotDataRef.current.get(traitName);
38951
- if (snapNow) {
38952
- snapNow.data[selfLinkedEntity] = rowsFromPayload;
38953
- reducerMirrorLog.info("write:self-emit", {
38954
- traitName,
38955
- eventKey,
38956
- linkedEntity: selfLinkedEntity,
38957
- rowCount: rowsFromPayload.length
38958
- });
38959
- }
38960
- }
38961
- }
38962
38873
  crossTraitLog.info("self:fire", { traitName, busKey: selfBusKey, eventKey });
38963
38874
  enqueueAndDrain(eventKey, event.payload);
38964
38875
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/ui",
3
- "version": "4.16.4",
3
+ "version": "4.18.0",
4
4
  "description": "React UI components, hooks, and providers for Almadar",
5
5
  "type": "module",
6
6
  "main": "./dist/components/index.js",
@@ -118,10 +118,10 @@
118
118
  "access": "public"
119
119
  },
120
120
  "dependencies": {
121
- "@almadar/core": "^7.7.1",
121
+ "@almadar/core": "^7.9.0",
122
122
  "@almadar/evaluator": ">=2.9.2",
123
123
  "@almadar/patterns": ">=2.17.1",
124
- "@almadar/runtime": "^5.11.1",
124
+ "@almadar/runtime": "^6.0.0",
125
125
  "@almadar/std": ">=6.4.1",
126
126
  "@almadar/syntax": ">=1.3.1",
127
127
  "@xyflow/react": "12.10.1",