@almadar/ui 5.158.0 → 5.159.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/{EntityBindingContext-Bn3ePJQC.d.cts → EntityBindingContext-0Evn_LcT.d.cts} +1 -1
- package/dist/{EntityBindingContext-Bn3ePJQC.d.ts → EntityBindingContext-0Evn_LcT.d.ts} +1 -1
- package/dist/avl/index.cjs +144 -34
- package/dist/avl/index.js +145 -35
- package/dist/components/index.cjs +192 -7
- package/dist/components/index.d.cts +8 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.js +193 -8
- package/dist/context/index.cjs +134 -39
- package/dist/context/index.js +92 -1
- package/dist/hooks/index.cjs +328 -233
- package/dist/hooks/index.js +93 -2
- package/dist/lib/index.cjs +92 -0
- package/dist/lib/index.d.cts +58 -1
- package/dist/lib/index.d.ts +58 -1
- package/dist/lib/index.js +62 -1
- package/dist/locales/index.cjs +3 -0
- package/dist/locales/index.js +3 -0
- package/dist/perf-DaVdsbU0.d.cts +21 -0
- package/dist/perf-DaVdsbU0.d.ts +21 -0
- package/dist/providers/index.cjs +256 -96
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +257 -97
- package/dist/runtime/index.cjs +152 -39
- package/dist/runtime/index.d.cts +5 -22
- package/dist/runtime/index.d.ts +5 -22
- package/dist/runtime/index.js +154 -40
- package/locales/ar.json +1 -0
- package/locales/en.json +1 -0
- package/locales/sl.json +1 -0
- package/package.json +5 -5
package/dist/runtime/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as React85 from 'react';
|
|
2
|
-
import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, Suspense, useState,
|
|
2
|
+
import React85__default, { createContext, useContext, useMemo, useRef, useEffect, useCallback, useSyncExternalStore, Suspense, useState, useLayoutEffect, lazy, useId } from 'react';
|
|
3
3
|
import { EventBusContext, useTraitScopeChain, RenderSlotProvider, useEntitySchemaOptional, useEntityBindingSnapshot, useTraitScope, useEntitySchema, getAllPages, matchPathAmong, CurrentPagePathProvider, NavStackProvider, OrbitalProvider, TraitScopeProvider, useNavStack, ServerBridgeProvider, useCurrentPagePath, useRenderSlot, useGameAudioContextOptional, VerificationProvider, EntitySchemaProvider, OrbitalThemeProvider, useServerBridge, EntityBindingContext } from '@almadar/ui/providers';
|
|
4
4
|
export { EntitySchemaProvider, ServerBridgeProvider, TraitContext, TraitProvider, useEntitySchema, useEntitySchemaOptional, useServerBridge, useTrait, useTraitContext } from '@almadar/ui/providers';
|
|
5
5
|
import { createLogger, setNamespaceLevel, isLogLevelEnabled } from '@almadar/logger';
|
|
6
|
+
import { perfStore, pushPerfEntry, wrapCallbackForEvent, perfStart, perfEnd, perfGauge, prepareSchemaForPreview, perfTimeAsync, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits } from '@almadar/runtime/ui';
|
|
7
|
+
export { PERF_NAMESPACE, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
6
8
|
import { StateMachineManager, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, createServerEffectHandlers, EffectExecutor, createContextFromBindings, createTickScheduler, isValidCronExpression, parseDurationString, InMemoryPersistence, normalizeCallSiteConfigToValues, interpolateValue } from '@almadar/runtime';
|
|
7
9
|
import { mergeEntityFrame, isCircuitEvent, applyListenPayloadMapping, schemaToIR, getPage, clearSchemaCache as clearSchemaCache$1, walkSExpr, buildResolvedTraitConfigs, isRenderBindingMarker, isFileValue, isInlineTrait, containsEntityBinding, isSExpr, isEventPayloadValue, RENDER_BINDING_MARKER, ANIMATION_NAMES } from '@almadar/core';
|
|
8
10
|
import { clsx } from 'clsx';
|
|
@@ -14,8 +16,6 @@ import { createPortal } from 'react-dom';
|
|
|
14
16
|
import { useTranslate } from '@almadar/ui/hooks';
|
|
15
17
|
import { useUISlots, UISlotProvider, useTheme } from '@almadar/ui/context';
|
|
16
18
|
import { evaluateGuard, evaluateListenPayloadExpr, evaluate, createMinimalContext, executeEffects } from '@almadar/evaluator';
|
|
17
|
-
import { wrapCallbackForEvent, prepareSchemaForPreview, perfStore, pushPerfEntry, collectTraitRefsFromResolvedTrait, buildOrbitalsByTrait, collectEmbeddedTraits } from '@almadar/runtime/ui';
|
|
18
|
-
export { PERF_NAMESPACE, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
19
19
|
import { Link, Outlet, useLocation } from 'react-router-dom';
|
|
20
20
|
import ELK from 'elkjs/lib/elk.bundled.js';
|
|
21
21
|
import SyntaxHighlighter from 'react-syntax-highlighter/dist/esm/prism-light.js';
|
|
@@ -793,6 +793,22 @@ var init_useTapReveal = __esm({
|
|
|
793
793
|
"hooks/useTapReveal.ts"() {
|
|
794
794
|
}
|
|
795
795
|
});
|
|
796
|
+
function usePerfBuffer() {
|
|
797
|
+
return useSyncExternalStore(perfStore.subscribe, perfStore.getSnapshot, perfStore.getSnapshot);
|
|
798
|
+
}
|
|
799
|
+
var profilerOnRender;
|
|
800
|
+
var init_perf = __esm({
|
|
801
|
+
"lib/perf.ts"() {
|
|
802
|
+
profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
803
|
+
pushPerfEntry({
|
|
804
|
+
name: `profiler:${id}:${phase}`,
|
|
805
|
+
durationMs: actualDuration,
|
|
806
|
+
ts: commitTime,
|
|
807
|
+
detail: { baseDuration }
|
|
808
|
+
});
|
|
809
|
+
};
|
|
810
|
+
}
|
|
811
|
+
});
|
|
796
812
|
function resolveMarkerExpression(expression, entity, config, state) {
|
|
797
813
|
const ctx = createContextFromBindings({
|
|
798
814
|
entity,
|
|
@@ -810,7 +826,16 @@ function isPlainObject(value) {
|
|
|
810
826
|
if (typeof value === "function") return false;
|
|
811
827
|
return true;
|
|
812
828
|
}
|
|
829
|
+
function isEvaluatorResolvedData(value) {
|
|
830
|
+
return evaluatorResolvedData.has(value);
|
|
831
|
+
}
|
|
832
|
+
function brandResolved(value) {
|
|
833
|
+
if (value !== null && typeof value === "object" && !React85__default.isValidElement(value) && !(value instanceof Date)) {
|
|
834
|
+
resolvedMarkerFree.add(value);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
813
837
|
function subtreeHasMarker(value) {
|
|
838
|
+
if (resolvedMarkerFree.has(value)) return false;
|
|
814
839
|
const cached = markerPresenceCache.get(value);
|
|
815
840
|
if (cached !== void 0) return cached;
|
|
816
841
|
let found = false;
|
|
@@ -832,10 +857,23 @@ function subtreeHasMarker(value) {
|
|
|
832
857
|
}
|
|
833
858
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
834
859
|
if (isRenderBindingMarker(value)) {
|
|
835
|
-
|
|
860
|
+
const cached = markerResolutionCache.get(value);
|
|
861
|
+
if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
|
|
862
|
+
return { resolved: cached.resolved, changed: false };
|
|
863
|
+
}
|
|
864
|
+
const resolved = resolveMarkerExpression(value.expression, entity, config, state);
|
|
865
|
+
markerResolutionCache.set(value, { entity, config, state, resolved });
|
|
866
|
+
if (resolved !== null && typeof resolved === "object" && !React85__default.isValidElement(resolved) && !(resolved instanceof Date)) {
|
|
867
|
+
resolvedMarkerFree.add(resolved);
|
|
868
|
+
evaluatorResolvedData.add(resolved);
|
|
869
|
+
}
|
|
870
|
+
return { resolved, changed: true };
|
|
836
871
|
}
|
|
837
872
|
if (Array.isArray(value)) {
|
|
838
|
-
if (!subtreeHasMarker(value))
|
|
873
|
+
if (!subtreeHasMarker(value)) {
|
|
874
|
+
brandResolved(value);
|
|
875
|
+
return { resolved: value, changed: false };
|
|
876
|
+
}
|
|
839
877
|
const out = [];
|
|
840
878
|
let changed = false;
|
|
841
879
|
for (const item of value) {
|
|
@@ -850,10 +888,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
850
888
|
out.push(resolved);
|
|
851
889
|
if (itemChanged) changed = true;
|
|
852
890
|
}
|
|
891
|
+
brandResolved(out);
|
|
853
892
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
854
893
|
}
|
|
855
894
|
if (isPlainObject(value)) {
|
|
856
|
-
if (!subtreeHasMarker(value))
|
|
895
|
+
if (!subtreeHasMarker(value)) {
|
|
896
|
+
brandResolved(value);
|
|
897
|
+
return { resolved: value, changed: false };
|
|
898
|
+
}
|
|
857
899
|
const sourceTrait = value._sourceTrait;
|
|
858
900
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
859
901
|
return { resolved: value, changed: false };
|
|
@@ -865,11 +907,13 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
865
907
|
out[key] = resolved;
|
|
866
908
|
if (itemChanged) changed = true;
|
|
867
909
|
}
|
|
910
|
+
brandResolved(out);
|
|
868
911
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
869
912
|
}
|
|
870
913
|
return { resolved: value, changed: false };
|
|
871
914
|
}
|
|
872
915
|
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
916
|
+
if (resolvedMarkerFree.has(props)) return props;
|
|
873
917
|
const out = {};
|
|
874
918
|
let changed = false;
|
|
875
919
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -877,13 +921,17 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
877
921
|
out[key] = resolved;
|
|
878
922
|
if (propChanged) changed = true;
|
|
879
923
|
}
|
|
924
|
+
brandResolved(out);
|
|
880
925
|
return changed ? out : props;
|
|
881
926
|
}
|
|
882
|
-
var markerPresenceCache;
|
|
927
|
+
var markerPresenceCache, markerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
|
|
883
928
|
var init_resolve_render_bindings = __esm({
|
|
884
929
|
"lib/resolve-render-bindings.ts"() {
|
|
885
930
|
"use client";
|
|
886
931
|
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
932
|
+
markerResolutionCache = /* @__PURE__ */ new WeakMap();
|
|
933
|
+
resolvedMarkerFree = /* @__PURE__ */ new WeakSet();
|
|
934
|
+
evaluatorResolvedData = /* @__PURE__ */ new WeakSet();
|
|
887
935
|
}
|
|
888
936
|
});
|
|
889
937
|
function cn(...inputs) {
|
|
@@ -12208,6 +12256,7 @@ var init_LearningCanvas = __esm({
|
|
|
12208
12256
|
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
12209
12257
|
"use client";
|
|
12210
12258
|
init_cn();
|
|
12259
|
+
init_perf();
|
|
12211
12260
|
init_useEventBus();
|
|
12212
12261
|
DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
|
|
12213
12262
|
TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
|
|
@@ -12251,6 +12300,7 @@ var init_LearningCanvas = __esm({
|
|
|
12251
12300
|
return [...shapes, ...traceOut, ...readoutOut];
|
|
12252
12301
|
}, [shapes, traces, readouts, width, height]);
|
|
12253
12302
|
const draw = useCallback(() => {
|
|
12303
|
+
const _perfT = perfStart("learningcanvas:paint");
|
|
12254
12304
|
const canvas = canvasRef.current;
|
|
12255
12305
|
if (!canvas) return;
|
|
12256
12306
|
const ctx = canvas.getContext("2d");
|
|
@@ -12272,6 +12322,7 @@ var init_LearningCanvas = __esm({
|
|
|
12272
12322
|
for (const shape of derivedShapes) {
|
|
12273
12323
|
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
12274
12324
|
}
|
|
12325
|
+
perfEnd("learningcanvas:paint", _perfT);
|
|
12275
12326
|
}, [width, height, backgroundColor, derivedShapes]);
|
|
12276
12327
|
useEffect(() => {
|
|
12277
12328
|
draw();
|
|
@@ -30098,6 +30149,7 @@ var init_MathCanvas = __esm({
|
|
|
30098
30149
|
"components/learning/molecules/MathCanvas.tsx"() {
|
|
30099
30150
|
"use client";
|
|
30100
30151
|
init_useEventBus();
|
|
30152
|
+
init_perf();
|
|
30101
30153
|
init_atoms();
|
|
30102
30154
|
init_Stack();
|
|
30103
30155
|
init_LearningCanvas();
|
|
@@ -30163,6 +30215,7 @@ var init_MathCanvas = __esm({
|
|
|
30163
30215
|
};
|
|
30164
30216
|
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30165
30217
|
const derivedShapes = useMemo(() => {
|
|
30218
|
+
const _perfT = perfStart("mathcanvas:derive");
|
|
30166
30219
|
const out = [];
|
|
30167
30220
|
const margin = 24;
|
|
30168
30221
|
const plotW = width - margin * 2;
|
|
@@ -30406,6 +30459,7 @@ var init_MathCanvas = __esm({
|
|
|
30406
30459
|
}
|
|
30407
30460
|
}
|
|
30408
30461
|
out.push(...shapes);
|
|
30462
|
+
perfEnd("mathcanvas:derive", _perfT);
|
|
30409
30463
|
return out;
|
|
30410
30464
|
}, [
|
|
30411
30465
|
width,
|
|
@@ -36621,7 +36675,7 @@ var init_RichBlockEditor = __esm({
|
|
|
36621
36675
|
{
|
|
36622
36676
|
variant: "bordered",
|
|
36623
36677
|
padding: "none",
|
|
36624
|
-
className: cn("flex flex-col", className),
|
|
36678
|
+
className: cn("flex flex-col text-card-foreground", className),
|
|
36625
36679
|
children: [
|
|
36626
36680
|
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsx(
|
|
36627
36681
|
Box,
|
|
@@ -41849,6 +41903,7 @@ var init_DetailPanel = __esm({
|
|
|
41849
41903
|
"use client";
|
|
41850
41904
|
init_atoms();
|
|
41851
41905
|
init_Box();
|
|
41906
|
+
init_Input();
|
|
41852
41907
|
init_Stack();
|
|
41853
41908
|
init_SimpleGrid();
|
|
41854
41909
|
init_Menu();
|
|
@@ -41864,6 +41919,7 @@ var init_DetailPanel = __esm({
|
|
|
41864
41919
|
ReactMarkdown2 = lazy(() => import('react-markdown'));
|
|
41865
41920
|
DetailPanel = ({
|
|
41866
41921
|
title: propTitle,
|
|
41922
|
+
onTitleCommit,
|
|
41867
41923
|
subtitle,
|
|
41868
41924
|
status,
|
|
41869
41925
|
avatar,
|
|
@@ -41885,6 +41941,7 @@ var init_DetailPanel = __esm({
|
|
|
41885
41941
|
}) => {
|
|
41886
41942
|
const eventBus = useEventBus();
|
|
41887
41943
|
const { t } = useTranslate();
|
|
41944
|
+
const [titleDraft, setTitleDraft] = React85__default.useState(null);
|
|
41888
41945
|
const isFieldDefArray = (arr) => {
|
|
41889
41946
|
if (!arr || arr.length === 0) return false;
|
|
41890
41947
|
const first = arr[0];
|
|
@@ -42105,6 +42162,50 @@ var init_DetailPanel = __esm({
|
|
|
42105
42162
|
}),
|
|
42106
42163
|
status && /* @__PURE__ */ jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
42107
42164
|
] });
|
|
42165
|
+
const commitTitle = () => {
|
|
42166
|
+
if (!onTitleCommit) return;
|
|
42167
|
+
const next = (titleDraft ?? "").trim();
|
|
42168
|
+
setTitleDraft(null);
|
|
42169
|
+
if (!next || next === title) return;
|
|
42170
|
+
onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
|
|
42171
|
+
};
|
|
42172
|
+
const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsx(
|
|
42173
|
+
Input,
|
|
42174
|
+
{
|
|
42175
|
+
value: titleDraft,
|
|
42176
|
+
autoFocus: true,
|
|
42177
|
+
"aria-label": t("common.title"),
|
|
42178
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
42179
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
42180
|
+
onBlur: commitTitle,
|
|
42181
|
+
onKeyDown: (e) => {
|
|
42182
|
+
if (e.key === "Enter") {
|
|
42183
|
+
e.preventDefault();
|
|
42184
|
+
commitTitle();
|
|
42185
|
+
} else if (e.key === "Escape") {
|
|
42186
|
+
e.preventDefault();
|
|
42187
|
+
setTitleDraft(null);
|
|
42188
|
+
}
|
|
42189
|
+
},
|
|
42190
|
+
"data-testid": "detail-title-input"
|
|
42191
|
+
}
|
|
42192
|
+
) : onTitleCommit ? /* @__PURE__ */ jsx(
|
|
42193
|
+
Box,
|
|
42194
|
+
{
|
|
42195
|
+
role: "button",
|
|
42196
|
+
tabIndex: 0,
|
|
42197
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
42198
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
42199
|
+
onKeyDown: (e) => {
|
|
42200
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
42201
|
+
e.preventDefault();
|
|
42202
|
+
setTitleDraft(title ?? "");
|
|
42203
|
+
}
|
|
42204
|
+
},
|
|
42205
|
+
"data-testid": "detail-title-editable",
|
|
42206
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
|
|
42207
|
+
}
|
|
42208
|
+
) : /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
|
|
42108
42209
|
const content = /* @__PURE__ */ jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
42109
42210
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
|
|
42110
42211
|
/* @__PURE__ */ jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
|
|
@@ -42124,7 +42225,7 @@ var init_DetailPanel = __esm({
|
|
|
42124
42225
|
avatar,
|
|
42125
42226
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
|
|
42126
42227
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
|
|
42127
|
-
|
|
42228
|
+
titleNode,
|
|
42128
42229
|
statusBadges
|
|
42129
42230
|
] }),
|
|
42130
42231
|
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
|
|
@@ -42685,7 +42786,7 @@ var init_Form = __esm({
|
|
|
42685
42786
|
});
|
|
42686
42787
|
debug(
|
|
42687
42788
|
"forms",
|
|
42688
|
-
`Calculation triggered: ${calc.variableName} = ${value}`
|
|
42789
|
+
`Calculation triggered: ${calc.variableName} = ${String(value)}`
|
|
42689
42790
|
);
|
|
42690
42791
|
}
|
|
42691
42792
|
});
|
|
@@ -49184,6 +49285,7 @@ function isPlainConfigObject(value) {
|
|
|
49184
49285
|
return proto === Object.prototype || proto === null;
|
|
49185
49286
|
}
|
|
49186
49287
|
function subtreeHasTraitRef(value) {
|
|
49288
|
+
if (isEvaluatorResolvedData(value)) return false;
|
|
49187
49289
|
const cached = traitRefPresenceCache.get(value);
|
|
49188
49290
|
if (cached !== void 0) return cached;
|
|
49189
49291
|
let found = false;
|
|
@@ -49256,6 +49358,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
|
|
|
49256
49358
|
};
|
|
49257
49359
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
49258
49360
|
} else if (Array.isArray(value)) {
|
|
49361
|
+
if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
|
|
49362
|
+
rendered[key] = value;
|
|
49363
|
+
continue;
|
|
49364
|
+
}
|
|
49259
49365
|
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
49260
49366
|
rendered[key] = value.map((item, i) => {
|
|
49261
49367
|
const el = item;
|
|
@@ -49734,6 +49840,9 @@ function enqueueEvent(queue, entry) {
|
|
|
49734
49840
|
}
|
|
49735
49841
|
queue.push(entry);
|
|
49736
49842
|
}
|
|
49843
|
+
|
|
49844
|
+
// hooks/useTraitStateMachine.ts
|
|
49845
|
+
init_perf();
|
|
49737
49846
|
var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
|
|
49738
49847
|
function isOperatorCall(value) {
|
|
49739
49848
|
const first = value[0];
|
|
@@ -50592,6 +50701,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50592
50701
|
}, [eventBus]);
|
|
50593
50702
|
useEffect(() => {
|
|
50594
50703
|
const scheduler = createTickScheduler();
|
|
50704
|
+
const timedTick = (key, fn) => () => perfTimeAsync(key, fn);
|
|
50595
50705
|
const pureWriterTickKeys = /* @__PURE__ */ new Set();
|
|
50596
50706
|
for (const group of sharedGroups.values()) {
|
|
50597
50707
|
const ticksByInterval = /* @__PURE__ */ new Map();
|
|
@@ -50608,12 +50718,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50608
50718
|
}
|
|
50609
50719
|
for (const entries of ticksByInterval.values()) {
|
|
50610
50720
|
const interval = entries[0].tick.interval;
|
|
50611
|
-
const onDue = () => {
|
|
50721
|
+
const onDue = timedTick(`tick:shared:${group.storeKey}@${String(interval)}`, () => {
|
|
50612
50722
|
const writers = entries.map(
|
|
50613
50723
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
50614
50724
|
);
|
|
50615
50725
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
50616
|
-
};
|
|
50726
|
+
});
|
|
50617
50727
|
if (interval === "frame") {
|
|
50618
50728
|
scheduler.add(0, onDue);
|
|
50619
50729
|
} else if (typeof interval === "number") {
|
|
@@ -50631,14 +50741,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50631
50741
|
if (sharedKey !== void 0 && pureWriterTickKeys.has(`${binding.trait.name}::${tick.name}`)) {
|
|
50632
50742
|
continue;
|
|
50633
50743
|
}
|
|
50744
|
+
const tickKey = `tick:${binding.trait.name}::${tick.name}`;
|
|
50634
50745
|
if (tick.interval === "frame") {
|
|
50635
|
-
scheduler.add(0, () => runTickEffects(tick, binding));
|
|
50746
|
+
scheduler.add(0, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50636
50747
|
} else if (typeof tick.interval === "number") {
|
|
50637
|
-
scheduler.add(tick.interval, () => runTickEffects(tick, binding));
|
|
50748
|
+
scheduler.add(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50638
50749
|
} else if (isValidCronExpression(tick.interval)) {
|
|
50639
|
-
scheduler.addCron(tick.interval, () => runTickEffects(tick, binding));
|
|
50750
|
+
scheduler.addCron(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50640
50751
|
} else {
|
|
50641
|
-
scheduler.add(parseDurationString(tick.interval), () => runTickEffects(tick, binding));
|
|
50752
|
+
scheduler.add(parseDurationString(tick.interval), timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50642
50753
|
}
|
|
50643
50754
|
}
|
|
50644
50755
|
}
|
|
@@ -50646,6 +50757,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50646
50757
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
50647
50758
|
const processEventQueued = useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50648
50759
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
50760
|
+
const _perfT0 = perfStart("processEvent:total");
|
|
50649
50761
|
const bindings = traitBindingsRef.current;
|
|
50650
50762
|
const currentManager = managerRef.current;
|
|
50651
50763
|
crossTraitLog.debug("processEvent:enter", () => ({
|
|
@@ -50669,6 +50781,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50669
50781
|
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
50670
50782
|
}
|
|
50671
50783
|
}
|
|
50784
|
+
const _perfT1 = perfStart("processEvent:guardMatch");
|
|
50672
50785
|
const results = currentManager.sendEvent(
|
|
50673
50786
|
normalizedEvent,
|
|
50674
50787
|
payload,
|
|
@@ -50677,6 +50790,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50677
50790
|
void 0,
|
|
50678
50791
|
targetTrait
|
|
50679
50792
|
);
|
|
50793
|
+
perfEnd("processEvent:guardMatch", _perfT1);
|
|
50680
50794
|
crossTraitLog.debug("processEvent:results", {
|
|
50681
50795
|
event: normalizedEvent,
|
|
50682
50796
|
executedCount: results.length,
|
|
@@ -50726,6 +50840,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50726
50840
|
transition: `${result.previousState} -> ${result.newState}`,
|
|
50727
50841
|
effects: JSON.stringify(result.effects)
|
|
50728
50842
|
}));
|
|
50843
|
+
const _perfT2 = perfStart("processEvent:executeAll");
|
|
50729
50844
|
const emittedDuringExec = await executeTransitionEffects({
|
|
50730
50845
|
binding,
|
|
50731
50846
|
// upstream gap: /runtime TransitionResult.effects is unknown[] — they are SExpr at runtime (see Almadar_UI_Gaps.md)
|
|
@@ -50737,6 +50852,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50737
50852
|
syncOnly: false,
|
|
50738
50853
|
log: stateLog
|
|
50739
50854
|
});
|
|
50855
|
+
perfEnd("processEvent:executeAll", _perfT2);
|
|
50740
50856
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
50741
50857
|
for (const emittedKey of emittedDuringExec) {
|
|
50742
50858
|
bridgeEchoPendingRef.current.set(
|
|
@@ -50833,27 +50949,31 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50833
50949
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
50834
50950
|
}
|
|
50835
50951
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
50836
|
-
|
|
50837
|
-
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50838
|
-
} else {
|
|
50839
|
-
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
50840
|
-
}
|
|
50952
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50841
50953
|
}
|
|
50954
|
+
perfEnd("processEvent:total", _perfT0);
|
|
50955
|
+
perfEnd(`event:${normalizedEvent}`, _perfT0);
|
|
50842
50956
|
}, [entities, eventBus, sharedEntityStore]);
|
|
50843
50957
|
const drainEventQueue = useCallback(async () => {
|
|
50844
50958
|
if (processingRef.current) return;
|
|
50845
50959
|
processingRef.current = true;
|
|
50960
|
+
const _perfT = perfStart("drain:pass");
|
|
50961
|
+
let _perfN = 0;
|
|
50846
50962
|
try {
|
|
50847
50963
|
while (eventQueueRef.current.length > 0) {
|
|
50848
50964
|
const entry = eventQueueRef.current.shift();
|
|
50965
|
+
_perfN++;
|
|
50849
50966
|
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
50850
50967
|
}
|
|
50851
50968
|
} finally {
|
|
50852
50969
|
processingRef.current = false;
|
|
50970
|
+
perfEnd("drain:pass", _perfT);
|
|
50971
|
+
perfGauge("drain:passEntries", _perfN);
|
|
50853
50972
|
}
|
|
50854
50973
|
}, [processEventQueued]);
|
|
50855
50974
|
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50856
50975
|
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
50976
|
+
perfGauge("queue:depthAtEnqueue", eventQueueRef.current.length);
|
|
50857
50977
|
void drainEventQueue();
|
|
50858
50978
|
}, [drainEventQueue]);
|
|
50859
50979
|
useCallback((eventKey, payload) => {
|
|
@@ -51255,7 +51375,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51255
51375
|
[serverActiveTraits]
|
|
51256
51376
|
);
|
|
51257
51377
|
const uiSlots = useUISlots();
|
|
51258
|
-
const onEventProcessed = useCallback(
|
|
51378
|
+
const onEventProcessed = useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
51259
51379
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
51260
51380
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
51261
51381
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -51269,9 +51389,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51269
51389
|
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
51270
51390
|
continue;
|
|
51271
51391
|
}
|
|
51272
|
-
|
|
51273
|
-
|
|
51274
|
-
|
|
51392
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload)).then(({ effects, meta }) => {
|
|
51393
|
+
recordServerResponse(name, event, meta);
|
|
51394
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
51395
|
+
});
|
|
51275
51396
|
}
|
|
51276
51397
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
51277
51398
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, navigateBack: onNavigateBack, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, navigateBack: onNavigateBack, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
@@ -51589,14 +51710,15 @@ function OrbPreview({
|
|
|
51589
51710
|
return pattern.replace(/:([A-Za-z0-9_]+)/g, (whole, key) => routeParams[key] ?? whole);
|
|
51590
51711
|
}, [currentPagePath, routeParams]);
|
|
51591
51712
|
const navStackRef = useRef(null);
|
|
51592
|
-
const handleNavigate = useCallback((path) => {
|
|
51713
|
+
const handleNavigate = useCallback((path, navState) => {
|
|
51593
51714
|
const hit = matchPathAmong(pages, path, (entry) => entry.page.path);
|
|
51594
51715
|
const match = hit?.candidate;
|
|
51595
|
-
const params = hit?.params ?? {};
|
|
51716
|
+
const params = { ...hit?.params ?? {}, ...navState ?? {} };
|
|
51596
51717
|
navLog.debug("handleNavigate", () => ({
|
|
51597
51718
|
path,
|
|
51598
51719
|
matched: match?.page.name ?? null,
|
|
51599
51720
|
params,
|
|
51721
|
+
navState: navState ? JSON.stringify(navState) : void 0,
|
|
51600
51722
|
availablePaths: pages.map((p) => p.page.path)
|
|
51601
51723
|
}));
|
|
51602
51724
|
if (match?.page.name) {
|
|
@@ -51611,9 +51733,9 @@ function OrbPreview({
|
|
|
51611
51733
|
}
|
|
51612
51734
|
}, [pages]);
|
|
51613
51735
|
const handleNavigateEffect = useCallback(
|
|
51614
|
-
(path,
|
|
51736
|
+
(path, params, crumb) => {
|
|
51615
51737
|
navStackRef.current?.beginNavigate(path, crumb);
|
|
51616
|
-
handleNavigate(path);
|
|
51738
|
+
handleNavigate(path, params);
|
|
51617
51739
|
},
|
|
51618
51740
|
[handleNavigate]
|
|
51619
51741
|
);
|
|
@@ -51768,16 +51890,8 @@ function BrowserPlayground({
|
|
|
51768
51890
|
}
|
|
51769
51891
|
);
|
|
51770
51892
|
}
|
|
51771
|
-
|
|
51772
|
-
|
|
51773
|
-
|
|
51774
|
-
var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
51775
|
-
pushPerfEntry({
|
|
51776
|
-
name: `profiler:${id}:${phase}`,
|
|
51777
|
-
durationMs: actualDuration,
|
|
51778
|
-
ts: commitTime,
|
|
51779
|
-
detail: { baseDuration }
|
|
51780
|
-
});
|
|
51781
|
-
};
|
|
51893
|
+
|
|
51894
|
+
// runtime/index.ts
|
|
51895
|
+
init_perf();
|
|
51782
51896
|
|
|
51783
51897
|
export { BrowserPlayground, OrbPreview, clearSchemaCache, createClientEffectHandlers, profilerOnRender, usePerfBuffer, useResolvedSchema, useTraitStateMachine };
|
package/locales/ar.json
CHANGED
package/locales/en.json
CHANGED
package/locales/sl.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.159.0",
|
|
4
4
|
"description": "React UI components, hooks, and providers for Almadar",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": [
|
|
@@ -118,11 +118,11 @@
|
|
|
118
118
|
"access": "public"
|
|
119
119
|
},
|
|
120
120
|
"dependencies": {
|
|
121
|
-
"@almadar/core": "^10.
|
|
122
|
-
"@almadar/evaluator": "^2.
|
|
121
|
+
"@almadar/core": "^10.69.0",
|
|
122
|
+
"@almadar/evaluator": "^2.42.0",
|
|
123
123
|
"@almadar/logger": "^1.11.0",
|
|
124
|
-
"@almadar/runtime": "^6.
|
|
125
|
-
"@almadar/std": "^16.
|
|
124
|
+
"@almadar/runtime": "^6.60.0",
|
|
125
|
+
"@almadar/std": "^16.185.0",
|
|
126
126
|
"@almadar/syntax": "^1.15.0",
|
|
127
127
|
"@dnd-kit/core": "^6.3.1",
|
|
128
128
|
"@dnd-kit/sortable": "^10.0.0",
|