@almadar/ui 5.158.0 → 5.160.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 +177 -54
- package/dist/avl/index.js +178 -55
- package/dist/components/index.cjs +225 -27
- package/dist/components/index.d.cts +8 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/index.js +226 -28
- 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 +289 -116
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/dist/providers/index.js +290 -117
- package/dist/runtime/index.cjs +185 -59
- package/dist/runtime/index.d.cts +5 -22
- package/dist/runtime/index.d.ts +5 -22
- package/dist/runtime/index.js +187 -60
- 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.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 };
|
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();
|
|
@@ -26054,8 +26105,8 @@ function DataGrid({
|
|
|
26054
26105
|
}
|
|
26055
26106
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
26056
26107
|
field.icon && renderIconInput(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
26057
|
-
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
26058
|
-
/* @__PURE__ */ jsx(Typography, { variant: "small", children: formatValue(value, field.format) })
|
|
26108
|
+
/* @__PURE__ */ jsx(Typography, { variant: "caption", color: "secondary", className: "sr-only", children: (field.label ?? fieldLabel2(field.name)) + ":" }),
|
|
26109
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue(value, field.format) })
|
|
26059
26110
|
] }, field.name);
|
|
26060
26111
|
}) })
|
|
26061
26112
|
] }) })
|
|
@@ -26483,7 +26534,11 @@ function DataList({
|
|
|
26483
26534
|
Box,
|
|
26484
26535
|
{
|
|
26485
26536
|
className: cn(
|
|
26486
|
-
|
|
26537
|
+
// items-start, not items-center: a multi-line row (title + meta +
|
|
26538
|
+
// progress) centred its action cluster in the vertical middle, so
|
|
26539
|
+
// the buttons floated between the meta fields instead of anchoring
|
|
26540
|
+
// to the title they act on (U-DATALIST-ACTIONS-FLOAT-MID-ROW).
|
|
26541
|
+
"group flex items-start gap-4 transition-all duration-fast",
|
|
26487
26542
|
isCompact ? "px-4 py-2" : "px-6 py-4",
|
|
26488
26543
|
"hover:bg-muted/80",
|
|
26489
26544
|
!isCard && !isCompact && "rounded-lg border border-transparent hover:border-border"
|
|
@@ -26514,11 +26569,19 @@ function DataList({
|
|
|
26514
26569
|
if (value === void 0 || value === null || value === "") return null;
|
|
26515
26570
|
return /* @__PURE__ */ jsxs(HStack, { gap: "xs", className: "items-center", children: [
|
|
26516
26571
|
field.icon && renderIconInput2(field.icon, { size: "xs", className: "text-muted-foreground" }),
|
|
26517
|
-
/* @__PURE__ */ jsxs(
|
|
26518
|
-
|
|
26519
|
-
|
|
26520
|
-
|
|
26521
|
-
|
|
26572
|
+
/* @__PURE__ */ jsxs(
|
|
26573
|
+
Typography,
|
|
26574
|
+
{
|
|
26575
|
+
variant: "caption",
|
|
26576
|
+
color: "secondary",
|
|
26577
|
+
className: cn(field.format !== "boolean" && "sr-only"),
|
|
26578
|
+
children: [
|
|
26579
|
+
field.label ?? fieldLabel3(field.name),
|
|
26580
|
+
":"
|
|
26581
|
+
]
|
|
26582
|
+
}
|
|
26583
|
+
),
|
|
26584
|
+
/* @__PURE__ */ jsx(Typography, { variant: "small", color: "secondary", children: formatValue2(value, field.format, { yes: t("common.yes"), no: t("common.no") }) })
|
|
26522
26585
|
] }, field.name);
|
|
26523
26586
|
}) }),
|
|
26524
26587
|
progressFields.map((field) => {
|
|
@@ -26537,7 +26600,7 @@ function DataList({
|
|
|
26537
26600
|
]
|
|
26538
26601
|
}
|
|
26539
26602
|
),
|
|
26540
|
-
isCard && !isLast && /* @__PURE__ */ jsx(Box, { className: "
|
|
26603
|
+
(isCard || isCompact) && !isLast && /* @__PURE__ */ jsx(Box, { className: cn("border-b border-border/40", isCompact ? "mx-4" : "mx-6") })
|
|
26541
26604
|
] }, id)
|
|
26542
26605
|
);
|
|
26543
26606
|
};
|
|
@@ -26547,7 +26610,13 @@ function DataList({
|
|
|
26547
26610
|
{
|
|
26548
26611
|
className: cn(
|
|
26549
26612
|
isCard && "bg-card rounded-xl border border-border shadow-elevation-dialog overflow-hidden",
|
|
26550
|
-
|
|
26613
|
+
// `gap-*` is inert on a block container, and Box only emits a display
|
|
26614
|
+
// class when its `display` prop is set — so every non-card list had
|
|
26615
|
+
// been asking for a gap that CSS silently dropped. flex-col makes it
|
|
26616
|
+
// real. `compact` keeps gap-0 on purpose: it separates with the row
|
|
26617
|
+
// divider above instead, never both (Almadar_UI_Beauty.md 6).
|
|
26618
|
+
!isCard && "flex flex-col",
|
|
26619
|
+
!isCard && !isCompact && gapClass,
|
|
26551
26620
|
listLookStyles[look],
|
|
26552
26621
|
className
|
|
26553
26622
|
),
|
|
@@ -30098,6 +30167,7 @@ var init_MathCanvas = __esm({
|
|
|
30098
30167
|
"components/learning/molecules/MathCanvas.tsx"() {
|
|
30099
30168
|
"use client";
|
|
30100
30169
|
init_useEventBus();
|
|
30170
|
+
init_perf();
|
|
30101
30171
|
init_atoms();
|
|
30102
30172
|
init_Stack();
|
|
30103
30173
|
init_LearningCanvas();
|
|
@@ -30163,6 +30233,7 @@ var init_MathCanvas = __esm({
|
|
|
30163
30233
|
};
|
|
30164
30234
|
}, [stableKeyMap, stableKeyUpMap, eventBus]);
|
|
30165
30235
|
const derivedShapes = useMemo(() => {
|
|
30236
|
+
const _perfT = perfStart("mathcanvas:derive");
|
|
30166
30237
|
const out = [];
|
|
30167
30238
|
const margin = 24;
|
|
30168
30239
|
const plotW = width - margin * 2;
|
|
@@ -30406,6 +30477,7 @@ var init_MathCanvas = __esm({
|
|
|
30406
30477
|
}
|
|
30407
30478
|
}
|
|
30408
30479
|
out.push(...shapes);
|
|
30480
|
+
perfEnd("mathcanvas:derive", _perfT);
|
|
30409
30481
|
return out;
|
|
30410
30482
|
}, [
|
|
30411
30483
|
width,
|
|
@@ -36621,7 +36693,7 @@ var init_RichBlockEditor = __esm({
|
|
|
36621
36693
|
{
|
|
36622
36694
|
variant: "bordered",
|
|
36623
36695
|
padding: "none",
|
|
36624
|
-
className: cn("flex flex-col", className),
|
|
36696
|
+
className: cn("flex flex-col text-card-foreground", className),
|
|
36625
36697
|
children: [
|
|
36626
36698
|
enableBlocks && showToolbar && !readOnly && /* @__PURE__ */ jsx(
|
|
36627
36699
|
Box,
|
|
@@ -41849,6 +41921,7 @@ var init_DetailPanel = __esm({
|
|
|
41849
41921
|
"use client";
|
|
41850
41922
|
init_atoms();
|
|
41851
41923
|
init_Box();
|
|
41924
|
+
init_Input();
|
|
41852
41925
|
init_Stack();
|
|
41853
41926
|
init_SimpleGrid();
|
|
41854
41927
|
init_Menu();
|
|
@@ -41864,6 +41937,7 @@ var init_DetailPanel = __esm({
|
|
|
41864
41937
|
ReactMarkdown2 = lazy(() => import('react-markdown'));
|
|
41865
41938
|
DetailPanel = ({
|
|
41866
41939
|
title: propTitle,
|
|
41940
|
+
onTitleCommit,
|
|
41867
41941
|
subtitle,
|
|
41868
41942
|
status,
|
|
41869
41943
|
avatar,
|
|
@@ -41885,6 +41959,7 @@ var init_DetailPanel = __esm({
|
|
|
41885
41959
|
}) => {
|
|
41886
41960
|
const eventBus = useEventBus();
|
|
41887
41961
|
const { t } = useTranslate();
|
|
41962
|
+
const [titleDraft, setTitleDraft] = React85__default.useState(null);
|
|
41888
41963
|
const isFieldDefArray = (arr) => {
|
|
41889
41964
|
if (!arr || arr.length === 0) return false;
|
|
41890
41965
|
const first = arr[0];
|
|
@@ -42105,6 +42180,50 @@ var init_DetailPanel = __esm({
|
|
|
42105
42180
|
}),
|
|
42106
42181
|
status && /* @__PURE__ */ jsx(Badge, { variant: status.variant ?? "default", children: status.label })
|
|
42107
42182
|
] });
|
|
42183
|
+
const commitTitle = () => {
|
|
42184
|
+
if (!onTitleCommit) return;
|
|
42185
|
+
const next = (titleDraft ?? "").trim();
|
|
42186
|
+
setTitleDraft(null);
|
|
42187
|
+
if (!next || next === title) return;
|
|
42188
|
+
onTitleCommit(next, normalizedData?.id !== void 0 ? String(normalizedData.id) : "");
|
|
42189
|
+
};
|
|
42190
|
+
const titleNode = onTitleCommit && titleDraft !== null ? /* @__PURE__ */ jsx(
|
|
42191
|
+
Input,
|
|
42192
|
+
{
|
|
42193
|
+
value: titleDraft,
|
|
42194
|
+
autoFocus: true,
|
|
42195
|
+
"aria-label": t("common.title"),
|
|
42196
|
+
className: "h-auto py-1 text-3xl font-bold tracking-tight",
|
|
42197
|
+
onChange: (e) => setTitleDraft(e.target.value),
|
|
42198
|
+
onBlur: commitTitle,
|
|
42199
|
+
onKeyDown: (e) => {
|
|
42200
|
+
if (e.key === "Enter") {
|
|
42201
|
+
e.preventDefault();
|
|
42202
|
+
commitTitle();
|
|
42203
|
+
} else if (e.key === "Escape") {
|
|
42204
|
+
e.preventDefault();
|
|
42205
|
+
setTitleDraft(null);
|
|
42206
|
+
}
|
|
42207
|
+
},
|
|
42208
|
+
"data-testid": "detail-title-input"
|
|
42209
|
+
}
|
|
42210
|
+
) : onTitleCommit ? /* @__PURE__ */ jsx(
|
|
42211
|
+
Box,
|
|
42212
|
+
{
|
|
42213
|
+
role: "button",
|
|
42214
|
+
tabIndex: 0,
|
|
42215
|
+
className: "cursor-text rounded px-1 -mx-1 transition-colors hover:bg-muted/40",
|
|
42216
|
+
onClick: () => setTitleDraft(title ?? ""),
|
|
42217
|
+
onKeyDown: (e) => {
|
|
42218
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
42219
|
+
e.preventDefault();
|
|
42220
|
+
setTitleDraft(title ?? "");
|
|
42221
|
+
}
|
|
42222
|
+
},
|
|
42223
|
+
"data-testid": "detail-title-editable",
|
|
42224
|
+
children: /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" })
|
|
42225
|
+
}
|
|
42226
|
+
) : /* @__PURE__ */ jsx(Typography, { variant: "h2", weight: "bold", children: title || "Details" });
|
|
42108
42227
|
const content = /* @__PURE__ */ jsx(Card, { variant: "elevated", children: /* @__PURE__ */ jsxs(VStack, { gap: "md", className: "p-6", children: [
|
|
42109
42228
|
/* @__PURE__ */ jsxs(HStack, { justify: "between", align: "start", gap: "md", children: [
|
|
42110
42229
|
/* @__PURE__ */ jsxs(HStack, { align: "start", gap: "sm", className: "min-w-0", children: [
|
|
@@ -42124,7 +42243,7 @@ var init_DetailPanel = __esm({
|
|
|
42124
42243
|
avatar,
|
|
42125
42244
|
/* @__PURE__ */ jsxs(VStack, { gap: "xs", className: "min-w-0", children: [
|
|
42126
42245
|
/* @__PURE__ */ jsxs(HStack, { align: "center", gap: "sm", wrap: true, children: [
|
|
42127
|
-
|
|
42246
|
+
titleNode,
|
|
42128
42247
|
statusBadges
|
|
42129
42248
|
] }),
|
|
42130
42249
|
subtitle && /* @__PURE__ */ jsx(Typography, { variant: "body", color: "secondary", children: subtitle })
|
|
@@ -42224,16 +42343,11 @@ var init_DetailPanel = __esm({
|
|
|
42224
42343
|
footer
|
|
42225
42344
|
] })
|
|
42226
42345
|
] }) });
|
|
42227
|
-
|
|
42228
|
-
Box,
|
|
42229
|
-
|
|
42230
|
-
|
|
42231
|
-
|
|
42232
|
-
className
|
|
42233
|
-
),
|
|
42234
|
-
children: content
|
|
42235
|
-
}
|
|
42236
|
-
);
|
|
42346
|
+
if (!slideOver) {
|
|
42347
|
+
return /* @__PURE__ */ jsx(Box, { className, children: content });
|
|
42348
|
+
}
|
|
42349
|
+
const panel = /* @__PURE__ */ jsx(Box, { className: cn("fixed inset-y-0 right-0 w-full max-w-2xl bg-card shadow-lg z-50 overflow-y-auto p-6", className), children: content });
|
|
42350
|
+
return typeof document === "undefined" ? panel : createPortal(panel, document.body);
|
|
42237
42351
|
};
|
|
42238
42352
|
DetailPanel.displayName = "DetailPanel";
|
|
42239
42353
|
}
|
|
@@ -42685,7 +42799,7 @@ var init_Form = __esm({
|
|
|
42685
42799
|
});
|
|
42686
42800
|
debug(
|
|
42687
42801
|
"forms",
|
|
42688
|
-
`Calculation triggered: ${calc.variableName} = ${value}`
|
|
42802
|
+
`Calculation triggered: ${calc.variableName} = ${String(value)}`
|
|
42689
42803
|
);
|
|
42690
42804
|
}
|
|
42691
42805
|
});
|
|
@@ -49184,6 +49298,7 @@ function isPlainConfigObject(value) {
|
|
|
49184
49298
|
return proto === Object.prototype || proto === null;
|
|
49185
49299
|
}
|
|
49186
49300
|
function subtreeHasTraitRef(value) {
|
|
49301
|
+
if (isEvaluatorResolvedData(value)) return false;
|
|
49187
49302
|
const cached = traitRefPresenceCache.get(value);
|
|
49188
49303
|
if (cached !== void 0) return cached;
|
|
49189
49304
|
let found = false;
|
|
@@ -49256,6 +49371,10 @@ function renderPatternProps(props, onDismiss, propsSchema) {
|
|
|
49256
49371
|
};
|
|
49257
49372
|
rendered[key] = /* @__PURE__ */ jsx(SlotContentRenderer, { content: childContent, onDismiss });
|
|
49258
49373
|
} else if (Array.isArray(value)) {
|
|
49374
|
+
if (!isEvaluatorResolvedData(value) && value.some((el) => isPatternConfig(el))) ; else if (!subtreeHasTraitRef(value)) {
|
|
49375
|
+
rendered[key] = value;
|
|
49376
|
+
continue;
|
|
49377
|
+
}
|
|
49259
49378
|
const isDataArray = propsSchema?.[key]?.items?.types?.includes("object") ?? false;
|
|
49260
49379
|
rendered[key] = value.map((item, i) => {
|
|
49261
49380
|
const el = item;
|
|
@@ -49734,6 +49853,9 @@ function enqueueEvent(queue, entry) {
|
|
|
49734
49853
|
}
|
|
49735
49854
|
queue.push(entry);
|
|
49736
49855
|
}
|
|
49856
|
+
|
|
49857
|
+
// hooks/useTraitStateMachine.ts
|
|
49858
|
+
init_perf();
|
|
49737
49859
|
var lambdaLog = createLogger("almadar:ui:fn-form-lambda");
|
|
49738
49860
|
function isOperatorCall(value) {
|
|
49739
49861
|
const first = value[0];
|
|
@@ -50592,6 +50714,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50592
50714
|
}, [eventBus]);
|
|
50593
50715
|
useEffect(() => {
|
|
50594
50716
|
const scheduler = createTickScheduler();
|
|
50717
|
+
const timedTick = (key, fn) => () => perfTimeAsync(key, fn);
|
|
50595
50718
|
const pureWriterTickKeys = /* @__PURE__ */ new Set();
|
|
50596
50719
|
for (const group of sharedGroups.values()) {
|
|
50597
50720
|
const ticksByInterval = /* @__PURE__ */ new Map();
|
|
@@ -50608,12 +50731,12 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50608
50731
|
}
|
|
50609
50732
|
for (const entries of ticksByInterval.values()) {
|
|
50610
50733
|
const interval = entries[0].tick.interval;
|
|
50611
|
-
const onDue = () => {
|
|
50734
|
+
const onDue = timedTick(`tick:shared:${group.storeKey}@${String(interval)}`, () => {
|
|
50612
50735
|
const writers = entries.map(
|
|
50613
50736
|
({ binding, tick }) => createSharedEntityWriter(binding, tick, traitStatesRef, emitFromSharedWriter)
|
|
50614
50737
|
);
|
|
50615
50738
|
runTickFrame(group.storeKey, writers, sharedEntityStore);
|
|
50616
|
-
};
|
|
50739
|
+
});
|
|
50617
50740
|
if (interval === "frame") {
|
|
50618
50741
|
scheduler.add(0, onDue);
|
|
50619
50742
|
} else if (typeof interval === "number") {
|
|
@@ -50631,14 +50754,15 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50631
50754
|
if (sharedKey !== void 0 && pureWriterTickKeys.has(`${binding.trait.name}::${tick.name}`)) {
|
|
50632
50755
|
continue;
|
|
50633
50756
|
}
|
|
50757
|
+
const tickKey = `tick:${binding.trait.name}::${tick.name}`;
|
|
50634
50758
|
if (tick.interval === "frame") {
|
|
50635
|
-
scheduler.add(0, () => runTickEffects(tick, binding));
|
|
50759
|
+
scheduler.add(0, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50636
50760
|
} else if (typeof tick.interval === "number") {
|
|
50637
|
-
scheduler.add(tick.interval, () => runTickEffects(tick, binding));
|
|
50761
|
+
scheduler.add(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50638
50762
|
} else if (isValidCronExpression(tick.interval)) {
|
|
50639
|
-
scheduler.addCron(tick.interval, () => runTickEffects(tick, binding));
|
|
50763
|
+
scheduler.addCron(tick.interval, timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50640
50764
|
} else {
|
|
50641
|
-
scheduler.add(parseDurationString(tick.interval), () => runTickEffects(tick, binding));
|
|
50765
|
+
scheduler.add(parseDurationString(tick.interval), timedTick(tickKey, () => runTickEffects(tick, binding)));
|
|
50642
50766
|
}
|
|
50643
50767
|
}
|
|
50644
50768
|
}
|
|
@@ -50646,6 +50770,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50646
50770
|
}, [traitBindings, runTickEffects, sharedGroups, sharedEntityStore, emitFromSharedWriter]);
|
|
50647
50771
|
const processEventQueued = useCallback(async (eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50648
50772
|
const normalizedEvent = normalizeEventKey(eventKey);
|
|
50773
|
+
const _perfT0 = perfStart("processEvent:total");
|
|
50649
50774
|
const bindings = traitBindingsRef.current;
|
|
50650
50775
|
const currentManager = managerRef.current;
|
|
50651
50776
|
crossTraitLog.debug("processEvent:enter", () => ({
|
|
@@ -50669,6 +50794,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50669
50794
|
entityByTrait[name] = { ...sharedEntityStore.getSnapshot(sharedKey) };
|
|
50670
50795
|
}
|
|
50671
50796
|
}
|
|
50797
|
+
const _perfT1 = perfStart("processEvent:guardMatch");
|
|
50672
50798
|
const results = currentManager.sendEvent(
|
|
50673
50799
|
normalizedEvent,
|
|
50674
50800
|
payload,
|
|
@@ -50677,6 +50803,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50677
50803
|
void 0,
|
|
50678
50804
|
targetTrait
|
|
50679
50805
|
);
|
|
50806
|
+
perfEnd("processEvent:guardMatch", _perfT1);
|
|
50680
50807
|
crossTraitLog.debug("processEvent:results", {
|
|
50681
50808
|
event: normalizedEvent,
|
|
50682
50809
|
executedCount: results.length,
|
|
@@ -50726,6 +50853,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50726
50853
|
transition: `${result.previousState} -> ${result.newState}`,
|
|
50727
50854
|
effects: JSON.stringify(result.effects)
|
|
50728
50855
|
}));
|
|
50856
|
+
const _perfT2 = perfStart("processEvent:executeAll");
|
|
50729
50857
|
const emittedDuringExec = await executeTransitionEffects({
|
|
50730
50858
|
binding,
|
|
50731
50859
|
// upstream gap: /runtime TransitionResult.effects is unknown[] — they are SExpr at runtime (see Almadar_UI_Gaps.md)
|
|
@@ -50737,6 +50865,7 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50737
50865
|
syncOnly: false,
|
|
50738
50866
|
log: stateLog
|
|
50739
50867
|
});
|
|
50868
|
+
perfEnd("processEvent:executeAll", _perfT2);
|
|
50740
50869
|
emittedByTrait.set(traitName, emittedDuringExec);
|
|
50741
50870
|
for (const emittedKey of emittedDuringExec) {
|
|
50742
50871
|
bridgeEchoPendingRef.current.set(
|
|
@@ -50833,27 +50962,31 @@ function useTraitStateMachine(traitBindings, uiSlots, options) {
|
|
|
50833
50962
|
if (orbital) dispatchedOrbitals.add(orbital);
|
|
50834
50963
|
}
|
|
50835
50964
|
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
|
-
}
|
|
50965
|
+
void onEventProcessed(normalizedEvent, relayPayload, dispatchedOrbitals, tick, sourceTrait);
|
|
50841
50966
|
}
|
|
50967
|
+
perfEnd("processEvent:total", _perfT0);
|
|
50968
|
+
perfEnd(`event:${normalizedEvent}`, _perfT0);
|
|
50842
50969
|
}, [entities, eventBus, sharedEntityStore]);
|
|
50843
50970
|
const drainEventQueue = useCallback(async () => {
|
|
50844
50971
|
if (processingRef.current) return;
|
|
50845
50972
|
processingRef.current = true;
|
|
50973
|
+
const _perfT = perfStart("drain:pass");
|
|
50974
|
+
let _perfN = 0;
|
|
50846
50975
|
try {
|
|
50847
50976
|
while (eventQueueRef.current.length > 0) {
|
|
50848
50977
|
const entry = eventQueueRef.current.shift();
|
|
50978
|
+
_perfN++;
|
|
50849
50979
|
await processEventQueued(entry.eventKey, entry.payload, entry.targetTrait, entry.tick, entry.sourceTrait);
|
|
50850
50980
|
}
|
|
50851
50981
|
} finally {
|
|
50852
50982
|
processingRef.current = false;
|
|
50983
|
+
perfEnd("drain:pass", _perfT);
|
|
50984
|
+
perfGauge("drain:passEntries", _perfN);
|
|
50853
50985
|
}
|
|
50854
50986
|
}, [processEventQueued]);
|
|
50855
50987
|
const enqueueAndDrain = useCallback((eventKey, payload, targetTrait, tick, sourceTrait) => {
|
|
50856
50988
|
enqueueEvent(eventQueueRef.current, { eventKey, payload, targetTrait, tick, sourceTrait });
|
|
50989
|
+
perfGauge("queue:depthAtEnqueue", eventQueueRef.current.length);
|
|
50857
50990
|
void drainEventQueue();
|
|
50858
50991
|
}, [drainEventQueue]);
|
|
50859
50992
|
useCallback((eventKey, payload) => {
|
|
@@ -51255,7 +51388,7 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51255
51388
|
[serverActiveTraits]
|
|
51256
51389
|
);
|
|
51257
51390
|
const uiSlots = useUISlots();
|
|
51258
|
-
const onEventProcessed = useCallback(
|
|
51391
|
+
const onEventProcessed = useCallback((event, payload, dispatchedOrbitals, tick, sourceTrait) => {
|
|
51259
51392
|
if (!bridge.connected || !orbitalNames?.length) return;
|
|
51260
51393
|
const targets = dispatchedOrbitals && dispatchedOrbitals.size > 0 ? orbitalNames.filter((n) => dispatchedOrbitals.has(n)) : orbitalNames;
|
|
51261
51394
|
xOrbitalLog.debug("TraitInitializer:fanout", () => ({
|
|
@@ -51269,9 +51402,10 @@ function TraitInitializer({ traits: traits2, routeParams, orbitalNames, onNaviga
|
|
|
51269
51402
|
void bridge.sendEvent(name, event, withActiveTraits(payload), tick, sourceTrait);
|
|
51270
51403
|
continue;
|
|
51271
51404
|
}
|
|
51272
|
-
|
|
51273
|
-
|
|
51274
|
-
|
|
51405
|
+
void bridge.sendEvent(name, event, withActiveTraits(payload)).then(({ effects, meta }) => {
|
|
51406
|
+
recordServerResponse(name, event, meta);
|
|
51407
|
+
applyServerEffects(effects, uiSlots, onNavigate, embeddedTraits, activeTraitNames, onNavigateBack);
|
|
51408
|
+
});
|
|
51275
51409
|
}
|
|
51276
51410
|
}, [bridge.connected, bridge.sendEvent, orbitalNames, uiSlots, onNavigate, onNavigateBack, embeddedTraits, activeTraitNames, withActiveTraits]);
|
|
51277
51411
|
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 +51723,15 @@ function OrbPreview({
|
|
|
51589
51723
|
return pattern.replace(/:([A-Za-z0-9_]+)/g, (whole, key) => routeParams[key] ?? whole);
|
|
51590
51724
|
}, [currentPagePath, routeParams]);
|
|
51591
51725
|
const navStackRef = useRef(null);
|
|
51592
|
-
const handleNavigate = useCallback((path) => {
|
|
51726
|
+
const handleNavigate = useCallback((path, navState) => {
|
|
51593
51727
|
const hit = matchPathAmong(pages, path, (entry) => entry.page.path);
|
|
51594
51728
|
const match = hit?.candidate;
|
|
51595
|
-
const params = hit?.params ?? {};
|
|
51729
|
+
const params = { ...hit?.params ?? {}, ...navState ?? {} };
|
|
51596
51730
|
navLog.debug("handleNavigate", () => ({
|
|
51597
51731
|
path,
|
|
51598
51732
|
matched: match?.page.name ?? null,
|
|
51599
51733
|
params,
|
|
51734
|
+
navState: navState ? JSON.stringify(navState) : void 0,
|
|
51600
51735
|
availablePaths: pages.map((p) => p.page.path)
|
|
51601
51736
|
}));
|
|
51602
51737
|
if (match?.page.name) {
|
|
@@ -51611,9 +51746,9 @@ function OrbPreview({
|
|
|
51611
51746
|
}
|
|
51612
51747
|
}, [pages]);
|
|
51613
51748
|
const handleNavigateEffect = useCallback(
|
|
51614
|
-
(path,
|
|
51749
|
+
(path, params, crumb) => {
|
|
51615
51750
|
navStackRef.current?.beginNavigate(path, crumb);
|
|
51616
|
-
handleNavigate(path);
|
|
51751
|
+
handleNavigate(path, params);
|
|
51617
51752
|
},
|
|
51618
51753
|
[handleNavigate]
|
|
51619
51754
|
);
|
|
@@ -51768,16 +51903,8 @@ function BrowserPlayground({
|
|
|
51768
51903
|
}
|
|
51769
51904
|
);
|
|
51770
51905
|
}
|
|
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
|
-
};
|
|
51906
|
+
|
|
51907
|
+
// runtime/index.ts
|
|
51908
|
+
init_perf();
|
|
51782
51909
|
|
|
51783
51910
|
export { BrowserPlayground, OrbPreview, clearSchemaCache, createClientEffectHandlers, profilerOnRender, usePerfBuffer, useResolvedSchema, useTraitStateMachine };
|
package/locales/ar.json
CHANGED
package/locales/en.json
CHANGED