@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.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
var React85 = require('react');
|
|
4
4
|
var providers = require('@almadar/ui/providers');
|
|
5
5
|
var logger = require('@almadar/logger');
|
|
6
|
+
var ui = require('@almadar/runtime/ui');
|
|
6
7
|
var runtime = require('@almadar/runtime');
|
|
7
8
|
var core = require('@almadar/core');
|
|
8
9
|
var clsx = require('clsx');
|
|
@@ -13,7 +14,6 @@ var reactDom = require('react-dom');
|
|
|
13
14
|
var hooks = require('@almadar/ui/hooks');
|
|
14
15
|
var context = require('@almadar/ui/context');
|
|
15
16
|
var evaluator = require('@almadar/evaluator');
|
|
16
|
-
var ui = require('@almadar/runtime/ui');
|
|
17
17
|
var reactRouterDom = require('react-router-dom');
|
|
18
18
|
var ELK = require('elkjs/lib/elk.bundled.js');
|
|
19
19
|
var SyntaxHighlighter = require('react-syntax-highlighter/dist/esm/prism-light.js');
|
|
@@ -867,6 +867,22 @@ var init_useTapReveal = __esm({
|
|
|
867
867
|
"hooks/useTapReveal.ts"() {
|
|
868
868
|
}
|
|
869
869
|
});
|
|
870
|
+
function usePerfBuffer() {
|
|
871
|
+
return React85.useSyncExternalStore(ui.perfStore.subscribe, ui.perfStore.getSnapshot, ui.perfStore.getSnapshot);
|
|
872
|
+
}
|
|
873
|
+
exports.profilerOnRender = void 0;
|
|
874
|
+
var init_perf = __esm({
|
|
875
|
+
"lib/perf.ts"() {
|
|
876
|
+
exports.profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
877
|
+
ui.pushPerfEntry({
|
|
878
|
+
name: `profiler:${id}:${phase}`,
|
|
879
|
+
durationMs: actualDuration,
|
|
880
|
+
ts: commitTime,
|
|
881
|
+
detail: { baseDuration }
|
|
882
|
+
});
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
});
|
|
870
886
|
function resolveMarkerExpression(expression, entity, config, state) {
|
|
871
887
|
const ctx = runtime.createContextFromBindings({
|
|
872
888
|
entity,
|
|
@@ -884,7 +900,16 @@ function isPlainObject(value) {
|
|
|
884
900
|
if (typeof value === "function") return false;
|
|
885
901
|
return true;
|
|
886
902
|
}
|
|
903
|
+
function isEvaluatorResolvedData(value) {
|
|
904
|
+
return evaluatorResolvedData.has(value);
|
|
905
|
+
}
|
|
906
|
+
function brandResolved(value) {
|
|
907
|
+
if (value !== null && typeof value === "object" && !React85__namespace.default.isValidElement(value) && !(value instanceof Date)) {
|
|
908
|
+
resolvedMarkerFree.add(value);
|
|
909
|
+
}
|
|
910
|
+
}
|
|
887
911
|
function subtreeHasMarker(value) {
|
|
912
|
+
if (resolvedMarkerFree.has(value)) return false;
|
|
888
913
|
const cached = markerPresenceCache.get(value);
|
|
889
914
|
if (cached !== void 0) return cached;
|
|
890
915
|
let found = false;
|
|
@@ -906,10 +931,23 @@ function subtreeHasMarker(value) {
|
|
|
906
931
|
}
|
|
907
932
|
function walkValue(value, scopeTrait, entity, config, state) {
|
|
908
933
|
if (core.isRenderBindingMarker(value)) {
|
|
909
|
-
|
|
934
|
+
const cached = markerResolutionCache.get(value);
|
|
935
|
+
if (cached !== void 0 && cached.entity === entity && cached.config === config && cached.state === state) {
|
|
936
|
+
return { resolved: cached.resolved, changed: false };
|
|
937
|
+
}
|
|
938
|
+
const resolved = resolveMarkerExpression(value.expression, entity, config, state);
|
|
939
|
+
markerResolutionCache.set(value, { entity, config, state, resolved });
|
|
940
|
+
if (resolved !== null && typeof resolved === "object" && !React85__namespace.default.isValidElement(resolved) && !(resolved instanceof Date)) {
|
|
941
|
+
resolvedMarkerFree.add(resolved);
|
|
942
|
+
evaluatorResolvedData.add(resolved);
|
|
943
|
+
}
|
|
944
|
+
return { resolved, changed: true };
|
|
910
945
|
}
|
|
911
946
|
if (Array.isArray(value)) {
|
|
912
|
-
if (!subtreeHasMarker(value))
|
|
947
|
+
if (!subtreeHasMarker(value)) {
|
|
948
|
+
brandResolved(value);
|
|
949
|
+
return { resolved: value, changed: false };
|
|
950
|
+
}
|
|
913
951
|
const out = [];
|
|
914
952
|
let changed = false;
|
|
915
953
|
for (const item of value) {
|
|
@@ -924,10 +962,14 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
924
962
|
out.push(resolved);
|
|
925
963
|
if (itemChanged) changed = true;
|
|
926
964
|
}
|
|
965
|
+
brandResolved(out);
|
|
927
966
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
928
967
|
}
|
|
929
968
|
if (isPlainObject(value)) {
|
|
930
|
-
if (!subtreeHasMarker(value))
|
|
969
|
+
if (!subtreeHasMarker(value)) {
|
|
970
|
+
brandResolved(value);
|
|
971
|
+
return { resolved: value, changed: false };
|
|
972
|
+
}
|
|
931
973
|
const sourceTrait = value._sourceTrait;
|
|
932
974
|
if (typeof sourceTrait === "string" && sourceTrait !== scopeTrait) {
|
|
933
975
|
return { resolved: value, changed: false };
|
|
@@ -939,11 +981,13 @@ function walkValue(value, scopeTrait, entity, config, state) {
|
|
|
939
981
|
out[key] = resolved;
|
|
940
982
|
if (itemChanged) changed = true;
|
|
941
983
|
}
|
|
984
|
+
brandResolved(out);
|
|
942
985
|
return changed ? { resolved: out, changed: true } : { resolved: value, changed: false };
|
|
943
986
|
}
|
|
944
987
|
return { resolved: value, changed: false };
|
|
945
988
|
}
|
|
946
989
|
function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
990
|
+
if (resolvedMarkerFree.has(props)) return props;
|
|
947
991
|
const out = {};
|
|
948
992
|
let changed = false;
|
|
949
993
|
for (const [key, value] of Object.entries(props)) {
|
|
@@ -951,13 +995,17 @@ function resolveRenderBindingMarkers(props, scopeTrait, entity, config, state) {
|
|
|
951
995
|
out[key] = resolved;
|
|
952
996
|
if (propChanged) changed = true;
|
|
953
997
|
}
|
|
998
|
+
brandResolved(out);
|
|
954
999
|
return changed ? out : props;
|
|
955
1000
|
}
|
|
956
|
-
var markerPresenceCache;
|
|
1001
|
+
var markerPresenceCache, markerResolutionCache, resolvedMarkerFree, evaluatorResolvedData;
|
|
957
1002
|
var init_resolve_render_bindings = __esm({
|
|
958
1003
|
"lib/resolve-render-bindings.ts"() {
|
|
959
1004
|
"use client";
|
|
960
1005
|
markerPresenceCache = /* @__PURE__ */ new WeakMap();
|
|
1006
|
+
markerResolutionCache = /* @__PURE__ */ new WeakMap();
|
|
1007
|
+
resolvedMarkerFree = /* @__PURE__ */ new WeakSet();
|
|
1008
|
+
evaluatorResolvedData = /* @__PURE__ */ new WeakSet();
|
|
961
1009
|
}
|
|
962
1010
|
});
|
|
963
1011
|
function cn(...inputs) {
|
|
@@ -12282,6 +12330,7 @@ var init_LearningCanvas = __esm({
|
|
|
12282
12330
|
"components/learning/atoms/LearningCanvas.tsx"() {
|
|
12283
12331
|
"use client";
|
|
12284
12332
|
init_cn();
|
|
12333
|
+
init_perf();
|
|
12285
12334
|
init_useEventBus();
|
|
12286
12335
|
DASH_PATTERNS = { dashed: [6, 4], dotted: [2, 3] };
|
|
12287
12336
|
TRACE_SERIES_COLORS = ["#2563eb", "#dc2626", "#16a34a", "#f59e0b"];
|
|
@@ -12325,6 +12374,7 @@ var init_LearningCanvas = __esm({
|
|
|
12325
12374
|
return [...shapes, ...traceOut, ...readoutOut];
|
|
12326
12375
|
}, [shapes, traces, readouts, width, height]);
|
|
12327
12376
|
const draw = React85.useCallback(() => {
|
|
12377
|
+
const _perfT = ui.perfStart("learningcanvas:paint");
|
|
12328
12378
|
const canvas = canvasRef.current;
|
|
12329
12379
|
if (!canvas) return;
|
|
12330
12380
|
const ctx = canvas.getContext("2d");
|
|
@@ -12346,6 +12396,7 @@ var init_LearningCanvas = __esm({
|
|
|
12346
12396
|
for (const shape of derivedShapes) {
|
|
12347
12397
|
if (shape.type === "text") drawShape(ctx, shape, width, height, derivedShapes);
|
|
12348
12398
|
}
|
|
12399
|
+
ui.perfEnd("learningcanvas:paint", _perfT);
|
|
12349
12400
|
}, [width, height, backgroundColor, derivedShapes]);
|
|
12350
12401
|
React85.useEffect(() => {
|
|
12351
12402
|
draw();
|
|
@@ -30172,6 +30223,7 @@ var init_MathCanvas = __esm({
|
|
|
30172
30223
|
"components/learning/molecules/MathCanvas.tsx"() {
|
|
30173
30224
|
"use client";
|
|
30174
30225
|
init_useEventBus();
|
|
30226
|
+
init_perf();
|
|
30175
30227
|
init_atoms();
|
|
30176
30228
|
init_Stack();
|
|
30177
30229
|
init_LearningCanvas();
|
|
@@ -30237,6 +30289,7 @@ var init_MathCanvas = __esm({
|
|
|
30237
30289
|
};
|
|
30238
30290
|
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30239
30291
|
const derivedShapes = React85.useMemo(() => {
|
|
30292
|
+
const _perfT = ui.perfStart("mathcanvas:derive");
|
|
30240
30293
|
const out = [];
|
|
30241
30294
|
const margin = 24;
|
|
30242
30295
|
const plotW = width - margin * 2;
|
|
@@ -30480,6 +30533,7 @@ var init_MathCanvas = __esm({
|
|
|
30480
30533
|
}
|
|
30481
30534
|
}
|
|
30482
30535
|
out.push(...shapes);
|
|
30536
|
+
ui.perfEnd("mathcanvas:derive", _perfT);
|
|
30483
30537
|
return out;
|
|
30484
30538
|
}, [
|
|
30485
30539
|
width,
|
|
@@ -36695,7 +36749,7 @@ var init_RichBlockEditor = __esm({
|
|
|
36695
36749
|
{
|
|
36696
36750
|
variant: "bordered",
|
|
36697
36751
|
padding: "none",
|
|
36698
|
-
className: cn("flex flex-col", className),
|
|
36752
|
+
className: cn("flex flex-col text-card-foreground", className),
|
|
36699
36753
|
children: [
|
|
36700
36754
|
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
36701
36755
|
Box,
|
|
@@ -41923,6 +41977,7 @@ var init_DetailPanel = __esm({
|
|
|
41923
41977
|
"use client";
|
|
41924
41978
|
init_atoms();
|
|
41925
41979
|
init_Box();
|
|
41980
|
+
init_Input();
|
|
41926
41981
|
init_Stack();
|
|
41927
41982
|
init_SimpleGrid();
|
|
41928
41983
|
init_Menu();
|
|
@@ -41938,6 +41993,7 @@ var init_DetailPanel = __esm({
|
|
|
41938
41993
|
ReactMarkdown2 = React85.lazy(() => import('react-markdown'));
|
|
41939
41994
|
DetailPanel = ({
|
|
41940
41995
|
title: propTitle,
|
|
41996
|
+
onTitleCommit,
|
|
41941
41997
|
subtitle,
|
|
41942
41998
|
status,
|
|
41943
41999
|
avatar,
|
|
@@ -41959,6 +42015,7 @@ var init_DetailPanel = __esm({
|
|
|
41959
42015
|
}) => {
|
|
41960
42016
|
const eventBus = useEventBus();
|
|
41961
42017
|
const { t } = hooks.useTranslate();
|
|
42018
|
+
const [titleDraft, setTitleDraft] = React85__namespace.default.useState(null);
|
|
41962
42019
|
const isFieldDefArray = (arr) => {
|
|
41963
42020
|
if (!arr || arr.length === 0) return false;
|
|
41964
42021
|
const first = arr[0];
|
|
@@ -42179,6 +42236,50 @@ var init_DetailPanel = __esm({
|
|
|
42179
42236
|
}),
|
|
42180
42237
|
status && /* @__PURE__ */ jsxRuntime.jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
42181
42238
|
] });
|
|
42239
|
+
const commitTitle = () => {
|
|
42240
|
+
if (!onTitleCommit) return;
|
|
42241
|
+
const next = (titleDraft ?? "").trim();
|
|
42242
|
+
setTitleDraft(null);
|
|
42243
|
+
if (!next || next === title) return;
|
|
42244
|
+
onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
|
|
42245
|
+
};
|
|
42246
|
+
const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
42247
|
+
Input,
|
|
42248
|
+
{
|
|
42249
|
+
value: titleDraft,
|
|
42250
|
+
autoFocus: true,
|
|
42251
|
+
"aria-label": t("common.title"),
|
|
42252
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
42253
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
42254
|
+
onBlur: commitTitle,
|
|
42255
|
+
onKeyDown: (e) => {
|
|
42256
|
+
if (e.key === "Enter") {
|
|
42257
|
+
e.preventDefault();
|
|
42258
|
+
commitTitle();
|
|
42259
|
+
} else if (e.key === "Escape") {
|
|
42260
|
+
e.preventDefault();
|
|
42261
|
+
setTitleDraft(null);
|
|
42262
|
+
}
|
|
42263
|
+
},
|
|
42264
|
+
"data-testid": "detail-title-input"
|
|
42265
|
+
}
|
|
42266
|
+
) : onTitleCommit ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
42267
|
+
Box,
|
|
42268
|
+
{
|
|
42269
|
+
role: "button",
|
|
42270
|
+
tabIndex: 0,
|
|
42271
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
42272
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
42273
|
+
onKeyDown: (e) => {
|
|
42274
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
42275
|
+
e.preventDefault();
|
|
42276
|
+
setTitleDraft(title ?? "");
|
|
42277
|
+
}
|
|
42278
|
+
},
|
|
42279
|
+
"data-testid": "detail-title-editable",
|
|
42280
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
|
|
42281
|
+
}
|
|
42282
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
|
|
42182
42283
|
const content = /* @__PURE__ */ jsxRuntime.jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
42183
42284
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
|
|
42184
42285
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
|
|
@@ -42198,7 +42299,7 @@ var init_DetailPanel = __esm({
|
|
|
42198
42299
|
avatar,
|
|
42199
42300
|
/* @__PURE__ */ jsxRuntime.jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
|
|
42200
42301
|
/* @__PURE__ */ jsxRuntime.jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
|
|
42201
|
-
|
|
42302
|
+
titleNode,
|
|
42202
42303
|
statusBadges
|
|
42203
42304
|
] }),
|
|
42204
42305
|
subtitle && /* @__PURE__ */ jsxRuntime.jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
|
|
@@ -42759,7 +42860,7 @@ var init_Form = __esm({
|
|
|
42759
42860
|
});
|
|
42760
42861
|
debug(
|
|
42761
42862
|
"forms",
|
|
42762
|
-
`Calculation triggered: ${calc.variableName} = ${value}`
|
|
42863
|
+
`Calculation triggered: ${calc.variableName} = ${String(value)}`
|
|
42763
42864
|
);
|
|
42764
42865
|
}
|
|
42765
42866
|
});
|
|
@@ -49258,6 +49359,7 @@ function isPlainConfigObject(value) {
|
|
|
49258
49359
|
return proto === Object.prototype || proto === null;
|
|
49259
49360
|
}
|
|
49260
49361
|
function subtreeHasTraitRef(value) {
|
|
49362
|
+
if (isEvaluatorResolvedData(value)) return false;
|
|
49261
49363
|
const cached = traitRefPresenceCache.get(value);
|
|
49262
49364
|
if (cached !== void 0) return cached;
|
|
49263
49365
|
let found = false;
|
|
@@ -49330,6 +49432,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
|
|
|
49330
49432
|
};
|
|
49331
49433
|
rendered[key] = /* @__PURE__ */ jsxRuntime.jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
49332
49434
|
} else if (Array.isArray(value)) {
|
|
49435
|
+
if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
|
|
49436
|
+
rendered[key] = value;
|
|
49437
|
+
continue;
|
|
49438
|
+
}
|
|
49333
49439
|
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
49334
49440
|
rendered[key] = value.map((item, i) => {
|
|
49335
49441
|
const el = item;
|
|
@@ -49808,6 +49914,9 @@ function enqueueEvent(queue, entry) {
|
|
|
49808
49914
|
}
|
|
49809
49915
|
queue.push(entry);
|
|
49810
49916
|
}
|
|
49917
|
+
|
|
49918
|
+
// hooks/useTraitStateMachine.ts
|
|
49919
|
+
init_perf();
|
|
49811
49920
|
var lambdaLog = logger.createLogger("almadar:ui:fn-form-lambda");
|
|
49812
49921
|
function isOperatorCall(value) {
|
|
49813
49922
|
const first = value[0];
|
|
@@ -50666,6 +50775,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50666
50775
|
}, [eventBus]);
|
|
50667
50776
|
React85.useEffect(() => {
|
|
50668
50777
|
const scheduler = runtime.createTickScheduler();
|
|
50778
|
+
const timedTick = (key, fn) => () => ui.perfTimeAsync(key, fn);
|
|
50669
50779
|
const pureWriterTickKeys = /* @__PURE__ */ new Set();
|
|
50670
50780
|
for (const group of sharedGroups.values()) {
|
|
50671
50781
|
const ticksByInterval = /* @__PURE__ */ new Map();
|
|
@@ -50682,12 +50792,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50682
50792
|
}
|
|
50683
50793
|
for (const entries of ticksByInterval.values()) {
|
|
50684
50794
|
const interval = entries[0].tick.interval;
|
|
50685
|
-
const onDue = () => {
|
|
50795
|
+
const onDue = timedTick(`tick:shared:${group.storeKey}@${String(interval)}`, () => {
|
|
50686
50796
|
const writers = entries.map(
|
|
50687
50797
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
50688
50798
|
);
|
|
50689
50799
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
50690
|
-
};
|
|
50800
|
+
});
|
|
50691
50801
|
if (interval === "frame") {
|
|
50692
50802
|
scheduler.add(0, onDue);
|
|
50693
50803
|
} else if (typeof interval === "number") {
|
|
@@ -50705,14 +50815,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50705
50815
|
if (sharedKey !== void 0 && pureWriterTickKeys.has(`${binding.trait.name}::${tick.name}`)) {
|
|
50706
50816
|
continue;
|
|
50707
50817
|
}
|
|
50818
|
+
const tickKey = `tick:${binding.trait.name}::${tick.name}`;
|
|
50708
50819
|
if (tick.interval === "frame") {
|
|
50709
|
-
scheduler.add(0, () => runTickEffects(tick, binding));
|
|
50820
|
+
scheduler.add(0, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50710
50821
|
} else if (typeof tick.interval === "number") {
|
|
50711
|
-
scheduler.add(tick.interval, () => runTickEffects(tick, binding));
|
|
50822
|
+
scheduler.add(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50712
50823
|
} else if (runtime.isValidCronExpression(tick.interval)) {
|
|
50713
|
-
scheduler.addCron(tick.interval, () => runTickEffects(tick, binding));
|
|
50824
|
+
scheduler.addCron(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50714
50825
|
} else {
|
|
50715
|
-
scheduler.add(runtime.parseDurationString(tick.interval), () => runTickEffects(tick, binding));
|
|
50826
|
+
scheduler.add(runtime.parseDurationString(tick.interval), timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50716
50827
|
}
|
|
50717
50828
|
}
|
|
50718
50829
|
}
|
|
@@ -50720,6 +50831,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50720
50831
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
50721
50832
|
const processEventQueued = React85.useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50722
50833
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
50834
|
+
const _perfT0 = ui.perfStart("processEvent:total");
|
|
50723
50835
|
const bindings = traitBindingsRef.current;
|
|
50724
50836
|
const currentManager = managerRef.current;
|
|
50725
50837
|
crossTraitLog.debug("processEvent:enter", () => ({
|
|
@@ -50743,6 +50855,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50743
50855
|
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
50744
50856
|
}
|
|
50745
50857
|
}
|
|
50858
|
+
const _perfT1 = ui.perfStart("processEvent:guardMatch");
|
|
50746
50859
|
const results = currentManager.sendEvent(
|
|
50747
50860
|
normalizedEvent,
|
|
50748
50861
|
payload,
|
|
@@ -50751,6 +50864,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50751
50864
|
void 0,
|
|
50752
50865
|
targetTrait
|
|
50753
50866
|
);
|
|
50867
|
+
ui.perfEnd("processEvent:guardMatch", _perfT1);
|
|
50754
50868
|
crossTraitLog.debug("processEvent:results", {
|
|
50755
50869
|
event: normalizedEvent,
|
|
50756
50870
|
executedCount: results.length,
|
|
@@ -50800,6 +50914,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50800
50914
|
transition: `${result.previousState} -> ${result.newState}`,
|
|
50801
50915
|
effects: JSON.stringify(result.effects)
|
|
50802
50916
|
}));
|
|
50917
|
+
const _perfT2 = ui.perfStart("processEvent:executeAll");
|
|
50803
50918
|
const emittedDuringExec = await executeTransitionEffects({
|
|
50804
50919
|
binding,
|
|
50805
50920
|
// upstream gap: /runtime TransitionResult.effects is unknown[] — they are SExpr at runtime (see Almadar_UI_Gaps.md)
|
|
@@ -50811,6 +50926,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50811
50926
|
syncOnly: false,
|
|
50812
50927
|
log: stateLog
|
|
50813
50928
|
});
|
|
50929
|
+
ui.perfEnd("processEvent:executeAll", _perfT2);
|
|
50814
50930
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
50815
50931
|
for (const emittedKey of emittedDuringExec) {
|
|
50816
50932
|
bridgeEchoPendingRef.current.set(
|
|
@@ -50907,27 +51023,31 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50907
51023
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
50908
51024
|
}
|
|
50909
51025
|
const relayPayload = targetTrait !== void 0 ? { ...payload ?? {}, _targetTrait: targetTrait } : payload;
|
|
50910
|
-
|
|
50911
|
-
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50912
|
-
} else {
|
|
50913
|
-
await onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals);
|
|
50914
|
-
}
|
|
51026
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50915
51027
|
}
|
|
51028
|
+
ui.perfEnd("processEvent:total", _perfT0);
|
|
51029
|
+
ui.perfEnd(`event:${normalizedEvent}`, _perfT0);
|
|
50916
51030
|
}, [entities, eventBus, sharedEntityStore]);
|
|
50917
51031
|
const drainEventQueue = React85.useCallback(async () => {
|
|
50918
51032
|
if (processingRef.current) return;
|
|
50919
51033
|
processingRef.current = true;
|
|
51034
|
+
const _perfT = ui.perfStart("drain:pass");
|
|
51035
|
+
let _perfN = 0;
|
|
50920
51036
|
try {
|
|
50921
51037
|
while (eventQueueRef.current.length > 0) {
|
|
50922
51038
|
const entry = eventQueueRef.current.shift();
|
|
51039
|
+
_perfN++;
|
|
50923
51040
|
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
50924
51041
|
}
|
|
50925
51042
|
} finally {
|
|
50926
51043
|
processingRef.current = false;
|
|
51044
|
+
ui.perfEnd("drain:pass", _perfT);
|
|
51045
|
+
ui.perfGauge("drain:passEntries", _perfN);
|
|
50927
51046
|
}
|
|
50928
51047
|
}, [processEventQueued]);
|
|
50929
51048
|
const enqueueAndDrain = React85.useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50930
51049
|
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
51050
|
+
ui.perfGauge("queue:depthAtEnqueue", eventQueueRef.current.length);
|
|
50931
51051
|
void drainEventQueue();
|
|
50932
51052
|
}, [drainEventQueue]);
|
|
50933
51053
|
React85.useCallback((eventKey, payload) => {
|
|
@@ -51329,7 +51449,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51329
51449
|
[serverActiveTraits]
|
|
51330
51450
|
);
|
|
51331
51451
|
const uiSlots = context.useUISlots();
|
|
51332
|
-
const onEventProcessed = React85.useCallback(
|
|
51452
|
+
const onEventProcessed = React85.useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
51333
51453
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
51334
51454
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
51335
51455
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -51343,9 +51463,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51343
51463
|
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
51344
51464
|
continue;
|
|
51345
51465
|
}
|
|
51346
|
-
|
|
51347
|
-
|
|
51348
|
-
|
|
51466
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload)).then(({ effects, meta }) => {
|
|
51467
|
+
recordServerResponse(name, event, meta);
|
|
51468
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
51469
|
+
});
|
|
51349
51470
|
}
|
|
51350
51471
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
51351
51472
|
const opts = orbitalNames ? { onEventProcessed, navigate: onNavigate, navigateBack: onNavigateBack, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams } : { navigate: onNavigate, navigateBack: onNavigateBack, persistence, traitConfigsByName, orbitalsByTrait, embeddedTraits, initPayload: routeParams };
|
|
@@ -51663,14 +51784,15 @@ function OrbPreview({
|
|
|
51663
51784
|
return pattern.replace(/:([A-Za-z0-9_]+)/g, (whole, key) => routeParams[key] ?? whole);
|
|
51664
51785
|
}, [currentPagePath, routeParams]);
|
|
51665
51786
|
const navStackRef = React85.useRef(null);
|
|
51666
|
-
const handleNavigate = React85.useCallback((path) => {
|
|
51787
|
+
const handleNavigate = React85.useCallback((path, navState) => {
|
|
51667
51788
|
const hit = providers.matchPathAmong(pages, path, (entry) => entry.page.path);
|
|
51668
51789
|
const match = hit?.candidate;
|
|
51669
|
-
const params = hit?.params ?? {};
|
|
51790
|
+
const params = { ...hit?.params ?? {}, ...navState ?? {} };
|
|
51670
51791
|
navLog.debug("handleNavigate", () => ({
|
|
51671
51792
|
path,
|
|
51672
51793
|
matched: match?.page.name ?? null,
|
|
51673
51794
|
params,
|
|
51795
|
+
navState: navState ? JSON.stringify(navState) : void 0,
|
|
51674
51796
|
availablePaths: pages.map((p) => p.page.path)
|
|
51675
51797
|
}));
|
|
51676
51798
|
if (match?.page.name) {
|
|
@@ -51685,9 +51807,9 @@ function OrbPreview({
|
|
|
51685
51807
|
}
|
|
51686
51808
|
}, [pages]);
|
|
51687
51809
|
const handleNavigateEffect = React85.useCallback(
|
|
51688
|
-
(path,
|
|
51810
|
+
(path, params, crumb) => {
|
|
51689
51811
|
navStackRef.current?.beginNavigate(path, crumb);
|
|
51690
|
-
handleNavigate(path);
|
|
51812
|
+
handleNavigate(path, params);
|
|
51691
51813
|
},
|
|
51692
51814
|
[handleNavigate]
|
|
51693
51815
|
);
|
|
@@ -51842,17 +51964,9 @@ function BrowserPlayground({
|
|
|
51842
51964
|
}
|
|
51843
51965
|
);
|
|
51844
51966
|
}
|
|
51845
|
-
|
|
51846
|
-
|
|
51847
|
-
|
|
51848
|
-
var profilerOnRender = (id, phase, actualDuration, baseDuration, _startTime, commitTime) => {
|
|
51849
|
-
ui.pushPerfEntry({
|
|
51850
|
-
name: `profiler:${id}:${phase}`,
|
|
51851
|
-
durationMs: actualDuration,
|
|
51852
|
-
ts: commitTime,
|
|
51853
|
-
detail: { baseDuration }
|
|
51854
|
-
});
|
|
51855
|
-
};
|
|
51967
|
+
|
|
51968
|
+
// runtime/index.ts
|
|
51969
|
+
init_perf();
|
|
51856
51970
|
|
|
51857
51971
|
Object.defineProperty(exports, "EntitySchemaProvider", {
|
|
51858
51972
|
enumerable: true,
|
|
@@ -51930,7 +52044,6 @@ exports.BrowserPlayground = BrowserPlayground;
|
|
|
51930
52044
|
exports.OrbPreview = OrbPreview;
|
|
51931
52045
|
exports.clearSchemaCache = clearSchemaCache;
|
|
51932
52046
|
exports.createClientEffectHandlers = createClientEffectHandlers;
|
|
51933
|
-
exports.profilerOnRender = profilerOnRender;
|
|
51934
52047
|
exports.usePerfBuffer = usePerfBuffer;
|
|
51935
52048
|
exports.useResolvedSchema = useResolvedSchema;
|
|
51936
52049
|
exports.useTraitStateMachine = useTraitStateMachine;
|
package/dist/runtime/index.d.cts
CHANGED
|
@@ -5,11 +5,11 @@ import * as _almadar_runtime from '@almadar/runtime';
|
|
|
5
5
|
import { TraitState, EffectHandlers } from '@almadar/runtime';
|
|
6
6
|
import '../useEventBus-Ckr4wqW3.cjs';
|
|
7
7
|
import { c as useUISlots } from '../UISlotContext-BlRDbHDy.cjs';
|
|
8
|
-
import {
|
|
9
|
-
export {
|
|
10
|
-
import { PerfEntry } from '@almadar/runtime/ui';
|
|
8
|
+
import { E as EntityBindingSource, S as ServerBridgeTransport } from '../EntityBindingContext-0Evn_LcT.cjs';
|
|
9
|
+
export { a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, d as ServerBridgeContextValue, e as ServerBridgeProvider, f as ServerClientEffect, T as TraitContext, g as TraitContextValue, h as TraitInstance, i as TraitProvider, j as TraitProviderProps, u as useEntitySchema, k as useEntitySchemaOptional, l as useServerBridge, m as useTrait, n as useTraitContext } from '../EntityBindingContext-0Evn_LcT.cjs';
|
|
11
10
|
export { PERF_NAMESPACE, PerfEntry, PreparedPreviewSchema, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
12
|
-
import React__default
|
|
11
|
+
import React__default from 'react';
|
|
12
|
+
export { p as profilerOnRender, u as usePerfBuffer } from '../perf-DaVdsbU0.cjs';
|
|
13
13
|
import '../event-bus-types-Bl78kokd.cjs';
|
|
14
14
|
import '../useUISlots-GNwGLlW2.cjs';
|
|
15
15
|
import '@almadar/core/patterns';
|
|
@@ -312,21 +312,4 @@ interface BrowserPlaygroundProps {
|
|
|
312
312
|
}
|
|
313
313
|
declare function BrowserPlayground({ schema, mode, initialPagePath, height, className, }: BrowserPlaygroundProps): React__default.ReactElement;
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
* @almadar/ui/runtime — perf instrumentation
|
|
317
|
-
*
|
|
318
|
-
* React-specific consumption layer on top of the renderer-agnostic perf ring
|
|
319
|
-
* now living in `@almadar/runtime/ui/perf`. Re-exports the framework-free
|
|
320
|
-
* timing primitives and adds `useSyncExternalStore` / `React.Profiler` hooks.
|
|
321
|
-
*/
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* React hook: returns the current perf ring snapshot, re-renders on push.
|
|
325
|
-
*/
|
|
326
|
-
declare function usePerfBuffer(): readonly PerfEntry[];
|
|
327
|
-
/**
|
|
328
|
-
* React.Profiler `onRender` callback. Records `actualDuration` per commit.
|
|
329
|
-
*/
|
|
330
|
-
declare const profilerOnRender: ProfilerOnRenderCallback;
|
|
331
|
-
|
|
332
|
-
export { BrowserPlayground, type BrowserPlaygroundProps, type ClientEventBus, type CreateClientEffectHandlersOptions, OrbPreview, type OrbPreviewProps, type ResolvedSchemaResult, ServerBridgeTransport, type SlotPatternEntry, type SlotSetter, type SlotSource, type TraitStateMachineResult, type UseTraitStateMachineOptions, clearSchemaCache, createClientEffectHandlers, profilerOnRender, usePerfBuffer, useResolvedSchema, useTraitStateMachine };
|
|
315
|
+
export { BrowserPlayground, type BrowserPlaygroundProps, type ClientEventBus, type CreateClientEffectHandlersOptions, OrbPreview, type OrbPreviewProps, type ResolvedSchemaResult, ServerBridgeTransport, type SlotPatternEntry, type SlotSetter, type SlotSource, type TraitStateMachineResult, type UseTraitStateMachineOptions, clearSchemaCache, createClientEffectHandlers, useResolvedSchema, useTraitStateMachine };
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ import * as _almadar_runtime from '@almadar/runtime';
|
|
|
5
5
|
import { TraitState, EffectHandlers } from '@almadar/runtime';
|
|
6
6
|
import '../useEventBus-CQWyAWpK.js';
|
|
7
7
|
import { c as useUISlots } from '../UISlotContext-CB89mv7N.js';
|
|
8
|
-
import {
|
|
9
|
-
export {
|
|
10
|
-
import { PerfEntry } from '@almadar/runtime/ui';
|
|
8
|
+
import { E as EntityBindingSource, S as ServerBridgeTransport } from '../EntityBindingContext-0Evn_LcT.js';
|
|
9
|
+
export { a as EntitySchemaContextValue, b as EntitySchemaProvider, c as EntitySchemaProviderProps, d as ServerBridgeContextValue, e as ServerBridgeProvider, f as ServerClientEffect, T as TraitContext, g as TraitContextValue, h as TraitInstance, i as TraitProvider, j as TraitProviderProps, u as useEntitySchema, k as useEntitySchemaOptional, l as useServerBridge, m as useTrait, n as useTraitContext } from '../EntityBindingContext-0Evn_LcT.js';
|
|
11
10
|
export { PERF_NAMESPACE, PerfEntry, PreparedPreviewSchema, adjustSchemaForMockData, buildMockData, clearPerf, perfEnd, perfStart, perfTime, prepareSchemaForPreview, wrapCallbackForEvent } from '@almadar/runtime/ui';
|
|
12
|
-
import React__default
|
|
11
|
+
import React__default from 'react';
|
|
12
|
+
export { p as profilerOnRender, u as usePerfBuffer } from '../perf-DaVdsbU0.js';
|
|
13
13
|
import '../event-bus-types-Bl78kokd.js';
|
|
14
14
|
import '../useUISlots-GNwGLlW2.js';
|
|
15
15
|
import '@almadar/core/patterns';
|
|
@@ -312,21 +312,4 @@ interface BrowserPlaygroundProps {
|
|
|
312
312
|
}
|
|
313
313
|
declare function BrowserPlayground({ schema, mode, initialPagePath, height, className, }: BrowserPlaygroundProps): React__default.ReactElement;
|
|
314
314
|
|
|
315
|
-
|
|
316
|
-
* @almadar/ui/runtime — perf instrumentation
|
|
317
|
-
*
|
|
318
|
-
* React-specific consumption layer on top of the renderer-agnostic perf ring
|
|
319
|
-
* now living in `@almadar/runtime/ui/perf`. Re-exports the framework-free
|
|
320
|
-
* timing primitives and adds `useSyncExternalStore` / `React.Profiler` hooks.
|
|
321
|
-
*/
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* React hook: returns the current perf ring snapshot, re-renders on push.
|
|
325
|
-
*/
|
|
326
|
-
declare function usePerfBuffer(): readonly PerfEntry[];
|
|
327
|
-
/**
|
|
328
|
-
* React.Profiler `onRender` callback. Records `actualDuration` per commit.
|
|
329
|
-
*/
|
|
330
|
-
declare const profilerOnRender: ProfilerOnRenderCallback;
|
|
331
|
-
|
|
332
|
-
export { BrowserPlayground, type BrowserPlaygroundProps, type ClientEventBus, type CreateClientEffectHandlersOptions, OrbPreview, type OrbPreviewProps, type ResolvedSchemaResult, ServerBridgeTransport, type SlotPatternEntry, type SlotSetter, type SlotSource, type TraitStateMachineResult, type UseTraitStateMachineOptions, clearSchemaCache, createClientEffectHandlers, profilerOnRender, usePerfBuffer, useResolvedSchema, useTraitStateMachine };
|
|
315
|
+
export { BrowserPlayground, type BrowserPlaygroundProps, type ClientEventBus, type CreateClientEffectHandlersOptions, OrbPreview, type OrbPreviewProps, type ResolvedSchemaResult, ServerBridgeTransport, type SlotPatternEntry, type SlotSetter, type SlotSource, type TraitStateMachineResult, type UseTraitStateMachineOptions, clearSchemaCache, createClientEffectHandlers, useResolvedSchema, useTraitStateMachine };
|