@rangka/client 0.1.1 → 0.1.3
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/App.d.ts.map +1 -1
- package/dist/App.js +7 -1
- package/dist/App.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -0
- package/dist/main.js.map +1 -1
- package/dist/shell/assets/index-63v1sBS3.css +1 -0
- package/dist/shell/assets/index-Dh7K40cQ.js +8634 -0
- package/dist/shell/assets/vendor-query-B2cydN5j.js +1 -0
- package/dist/shell/assets/vendor-radix-BJxYPxPb.js +69 -0
- package/dist/shell/assets/vendor-router-ET_myMt5.js +17 -0
- package/dist/shell/index.html +5 -2
- package/dist/theme.css +82 -0
- package/dist/widgets/components/lazy-manifest.d.ts +11 -0
- package/dist/widgets/components/lazy-manifest.d.ts.map +1 -0
- package/dist/widgets/components/lazy-manifest.js +32 -0
- package/dist/widgets/components/lazy-manifest.js.map +1 -0
- package/dist/widgets/components/register.js +12 -12
- package/dist/widgets/components/register.js.map +1 -1
- package/dist/widgets/loader.d.ts +3 -0
- package/dist/widgets/loader.d.ts.map +1 -0
- package/dist/widgets/loader.js +73 -0
- package/dist/widgets/loader.js.map +1 -0
- package/dist/widgets/renderer/LazyWidget.d.ts +8 -0
- package/dist/widgets/renderer/LazyWidget.d.ts.map +1 -0
- package/dist/widgets/renderer/LazyWidget.js +31 -0
- package/dist/widgets/renderer/LazyWidget.js.map +1 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.d.ts +17 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.d.ts.map +1 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.js +18 -0
- package/dist/widgets/renderer/WidgetErrorBoundary.js.map +1 -0
- package/dist/widgets/renderer/WidgetRenderer.d.ts.map +1 -1
- package/dist/widgets/renderer/WidgetRenderer.js +8 -6
- package/dist/widgets/renderer/WidgetRenderer.js.map +1 -1
- package/package.json +7 -4
- package/.claude/skills/add-widget/SKILL.md +0 -101
- package/.turbo/turbo-build.log +0 -29
- package/CHANGELOG.md +0 -25
- package/CLAUDE.md +0 -236
- package/components.json +0 -25
- package/dist/components/ui/chart.d.ts +0 -45
- package/dist/components/ui/chart.d.ts.map +0 -1
- package/dist/components/ui/chart.js +0 -119
- package/dist/components/ui/chart.js.map +0 -1
- package/dist/shell/assets/index--35CAvcP.js +0 -8715
- package/dist/shell/assets/index-COLmoPYo.css +0 -1
- package/index.html +0 -12
- package/src/App.tsx +0 -44
- package/src/__tests__/setup.ts +0 -1
- package/src/api/auth.ts +0 -41
- package/src/api/boot.ts +0 -10
- package/src/api/client.ts +0 -26
- package/src/api/paths.ts +0 -3
- package/src/api/token.ts +0 -13
- package/src/auth/LoginForm.tsx +0 -67
- package/src/auth/SessionExpired.tsx +0 -24
- package/src/auth/SetupForm.tsx +0 -76
- package/src/boot/BootGate.tsx +0 -35
- package/src/boot/BootProvider.tsx +0 -28
- package/src/boot/types.ts +0 -9
- package/src/boot/useBoot.ts +0 -111
- package/src/components/Icon.tsx +0 -17
- package/src/components/ui/accordion.tsx +0 -82
- package/src/components/ui/alert-dialog.tsx +0 -180
- package/src/components/ui/alert.tsx +0 -76
- package/src/components/ui/aspect-ratio.tsx +0 -9
- package/src/components/ui/avatar.tsx +0 -94
- package/src/components/ui/badge.tsx +0 -45
- package/src/components/ui/breadcrumb.tsx +0 -104
- package/src/components/ui/button-group.tsx +0 -78
- package/src/components/ui/button.tsx +0 -65
- package/src/components/ui/calendar.tsx +0 -187
- package/src/components/ui/card.tsx +0 -85
- package/src/components/ui/carousel.tsx +0 -229
- package/src/components/ui/chart.tsx +0 -339
- package/src/components/ui/checkbox.tsx +0 -27
- package/src/components/ui/collapsible.tsx +0 -21
- package/src/components/ui/combobox.tsx +0 -275
- package/src/components/ui/command.tsx +0 -178
- package/src/components/ui/context-menu.tsx +0 -242
- package/src/components/ui/dialog.tsx +0 -146
- package/src/components/ui/direction.tsx +0 -20
- package/src/components/ui/drawer.tsx +0 -118
- package/src/components/ui/dropdown-menu.tsx +0 -247
- package/src/components/ui/empty.tsx +0 -94
- package/src/components/ui/field.tsx +0 -224
- package/src/components/ui/hover-card.tsx +0 -36
- package/src/components/ui/input-group.tsx +0 -142
- package/src/components/ui/input-otp.tsx +0 -86
- package/src/components/ui/input.tsx +0 -19
- package/src/components/ui/item.tsx +0 -182
- package/src/components/ui/kbd.tsx +0 -26
- package/src/components/ui/label.tsx +0 -19
- package/src/components/ui/menubar.tsx +0 -260
- package/src/components/ui/native-select.tsx +0 -55
- package/src/components/ui/navigation-menu.tsx +0 -160
- package/src/components/ui/pagination.tsx +0 -112
- package/src/components/ui/popover.tsx +0 -74
- package/src/components/ui/progress.tsx +0 -31
- package/src/components/ui/radio-group.tsx +0 -42
- package/src/components/ui/resizable.tsx +0 -42
- package/src/components/ui/scroll-area.tsx +0 -53
- package/src/components/ui/select.tsx +0 -185
- package/src/components/ui/separator.tsx +0 -26
- package/src/components/ui/sheet.tsx +0 -128
- package/src/components/ui/sidebar.tsx +0 -669
- package/src/components/ui/skeleton.tsx +0 -13
- package/src/components/ui/slider.tsx +0 -54
- package/src/components/ui/sonner.tsx +0 -43
- package/src/components/ui/spinner.tsx +0 -16
- package/src/components/ui/switch.tsx +0 -33
- package/src/components/ui/table.tsx +0 -87
- package/src/components/ui/tabs.tsx +0 -80
- package/src/components/ui/textarea.tsx +0 -18
- package/src/components/ui/toggle-group.tsx +0 -86
- package/src/components/ui/toggle.tsx +0 -44
- package/src/components/ui/tooltip.tsx +0 -53
- package/src/context/MetaContext.tsx +0 -22
- package/src/context/ModuleContext.tsx +0 -62
- package/src/context/PermissionsContext.tsx +0 -39
- package/src/context/ShellProviders.tsx +0 -33
- package/src/context/UserContext.tsx +0 -16
- package/src/data/QueryProvider.tsx +0 -7
- package/src/data/queryClient.ts +0 -18
- package/src/data/useModelMeta.ts +0 -17
- package/src/data/useMutation.ts +0 -60
- package/src/data/useRecord.ts +0 -29
- package/src/data/useSource.ts +0 -112
- package/src/hooks/use-mobile.ts +0 -19
- package/src/index.css +0 -260
- package/src/index.ts +0 -16
- package/src/lib/utils.ts +0 -6
- package/src/main.tsx +0 -17
- package/src/router/NotFound.tsx +0 -8
- package/src/router/RouterProvider.tsx +0 -7
- package/src/router/buildRouteTree.tsx +0 -63
- package/src/router/createShellRouter.ts +0 -9
- package/src/router/hooks.ts +0 -43
- package/src/shell/CommandPalette.tsx +0 -76
- package/src/shell/ConfirmDialog.tsx +0 -34
- package/src/shell/ConfirmProvider.tsx +0 -56
- package/src/shell/DrawerContext.tsx +0 -44
- package/src/shell/HeaderActions.tsx +0 -31
- package/src/shell/ModuleSelectorPage.tsx +0 -149
- package/src/shell/PageOutlet.tsx +0 -21
- package/src/shell/ShellContext.tsx +0 -45
- package/src/shell/ShellDevTools.tsx +0 -153
- package/src/shell/ShellLayout.tsx +0 -231
- package/src/shell/Toast.tsx +0 -58
- package/src/shell/ToastProvider.tsx +0 -60
- package/src/shell/app-sidebar/AppSidebar.tsx +0 -44
- package/src/shell/app-sidebar/ModuleSwitcher.tsx +0 -87
- package/src/shell/app-sidebar/NavMain.tsx +0 -64
- package/src/shell/app-sidebar/NavUser.tsx +0 -97
- package/src/shell/app-sidebar/SearchMenu.tsx +0 -22
- package/src/shell/app-sidebar/index.ts +0 -8
- package/src/shell/app-sidebar/types.ts +0 -38
- package/src/shell/types.ts +0 -6
- package/src/shell/useBreadcrumbs.ts +0 -42
- package/src/studio/bridge.ts +0 -125
- package/src/studio/index.ts +0 -3
- package/src/studio/overlay.ts +0 -47
- package/src/studio/types.ts +0 -32
- package/src/studio/walker.ts +0 -48
- package/src/vite-env.d.ts +0 -1
- package/src/widgets/__tests__/action-edge-cases.test.ts +0 -281
- package/src/widgets/__tests__/action.test.ts +0 -236
- package/src/widgets/__tests__/attachment-widget.test.tsx +0 -85
- package/src/widgets/__tests__/attachments-widget.test.tsx +0 -109
- package/src/widgets/__tests__/binding.test.ts +0 -76
- package/src/widgets/__tests__/button-widget.test.tsx +0 -145
- package/src/widgets/__tests__/checkbox-widget.test.tsx +0 -158
- package/src/widgets/__tests__/code-widget.test.tsx +0 -64
- package/src/widgets/__tests__/computed-widget.test.tsx +0 -62
- package/src/widgets/__tests__/condition-edge-cases.test.ts +0 -120
- package/src/widgets/__tests__/condition.test.ts +0 -221
- package/src/widgets/__tests__/context.test.ts +0 -99
- package/src/widgets/__tests__/data-widget.test.tsx +0 -204
- package/src/widgets/__tests__/datepicker-widget.test.tsx +0 -66
- package/src/widgets/__tests__/datetime-widget.test.tsx +0 -67
- package/src/widgets/__tests__/drawer-widget.test.tsx +0 -149
- package/src/widgets/__tests__/dynamic-link-widget.test.tsx +0 -52
- package/src/widgets/__tests__/edge-cases.test.ts +0 -232
- package/src/widgets/__tests__/evaluator.test.ts +0 -107
- package/src/widgets/__tests__/functions.test.ts +0 -147
- package/src/widgets/__tests__/grid-widget.test.tsx +0 -137
- package/src/widgets/__tests__/hooks.test.tsx +0 -249
- package/src/widgets/__tests__/icon-widget.test.tsx +0 -129
- package/src/widgets/__tests__/input-widget.test.tsx +0 -264
- package/src/widgets/__tests__/integration.test.ts +0 -116
- package/src/widgets/__tests__/json-widget.test.tsx +0 -70
- package/src/widgets/__tests__/link-widget.test.tsx +0 -92
- package/src/widgets/__tests__/many-to-many-widget.test.tsx +0 -93
- package/src/widgets/__tests__/modal-widget.test.tsx +0 -148
- package/src/widgets/__tests__/money-widget.test.tsx +0 -97
- package/src/widgets/__tests__/parser.test.ts +0 -171
- package/src/widgets/__tests__/reactive-variables.test.ts +0 -383
- package/src/widgets/__tests__/renderer.test.tsx +0 -300
- package/src/widgets/__tests__/repeat-widget.test.tsx +0 -229
- package/src/widgets/__tests__/select-widget.test.tsx +0 -231
- package/src/widgets/__tests__/sequence-widget.test.tsx +0 -58
- package/src/widgets/__tests__/shell-integration.test.tsx +0 -1343
- package/src/widgets/__tests__/split-widget.test.tsx +0 -133
- package/src/widgets/__tests__/state-edge-cases.test.ts +0 -118
- package/src/widgets/__tests__/state.test.ts +0 -106
- package/src/widgets/__tests__/table-data-binding.test.tsx +0 -482
- package/src/widgets/__tests__/table-filter-popover.test.tsx +0 -486
- package/src/widgets/__tests__/table-search.test.tsx +0 -305
- package/src/widgets/__tests__/table-widget.test.tsx +0 -509
- package/src/widgets/__tests__/textarea-widget.test.tsx +0 -105
- package/src/widgets/__tests__/tracker-validator-edge-cases.test.ts +0 -242
- package/src/widgets/__tests__/tracker.test.ts +0 -133
- package/src/widgets/__tests__/tree-widget.test.tsx +0 -97
- package/src/widgets/__tests__/use-model-source.test.ts +0 -67
- package/src/widgets/__tests__/validator.test.ts +0 -208
- package/src/widgets/action/dispatcher.ts +0 -334
- package/src/widgets/action/index.ts +0 -2
- package/src/widgets/binding/index.ts +0 -2
- package/src/widgets/binding/resolver.ts +0 -61
- package/src/widgets/components/AttachmentWidget.tsx +0 -111
- package/src/widgets/components/AttachmentsWidget.tsx +0 -121
- package/src/widgets/components/BadgeWidget.tsx +0 -35
- package/src/widgets/components/ButtonWidget.tsx +0 -43
- package/src/widgets/components/CardWidget.tsx +0 -68
- package/src/widgets/components/CheckboxWidget.tsx +0 -39
- package/src/widgets/components/CodeWidget.tsx +0 -44
- package/src/widgets/components/ColumnWidget.tsx +0 -22
- package/src/widgets/components/ComputedWidget.tsx +0 -49
- package/src/widgets/components/DataWidget.tsx +0 -189
- package/src/widgets/components/DatePickerWidget.tsx +0 -73
- package/src/widgets/components/DatetimeWidget.tsx +0 -160
- package/src/widgets/components/DividerWidget.tsx +0 -37
- package/src/widgets/components/DrawerWidget.tsx +0 -52
- package/src/widgets/components/DynamicLinkWidget.tsx +0 -130
- package/src/widgets/components/GridWidget.tsx +0 -134
- package/src/widgets/components/GroupWidget.tsx +0 -111
- package/src/widgets/components/IconWidget.tsx +0 -29
- package/src/widgets/components/ImageWidget.tsx +0 -28
- package/src/widgets/components/InputWidget.tsx +0 -70
- package/src/widgets/components/JsonWidget.tsx +0 -78
- package/src/widgets/components/LinkWidget.tsx +0 -99
- package/src/widgets/components/ManyToManyWidget.tsx +0 -125
- package/src/widgets/components/ModalWidget.tsx +0 -52
- package/src/widgets/components/MoneyWidget.tsx +0 -80
- package/src/widgets/components/RepeatWidget.tsx +0 -66
- package/src/widgets/components/ScrollAreaWidget.tsx +0 -40
- package/src/widgets/components/SectionWidget.tsx +0 -78
- package/src/widgets/components/SelectWidget.tsx +0 -63
- package/src/widgets/components/SequenceWidget.tsx +0 -32
- package/src/widgets/components/SpacerWidget.tsx +0 -29
- package/src/widgets/components/SplitWidget.tsx +0 -60
- package/src/widgets/components/StackWidget.tsx +0 -44
- package/src/widgets/components/TableWidget.tsx +0 -366
- package/src/widgets/components/TextWidget.tsx +0 -44
- package/src/widgets/components/TextareaWidget.tsx +0 -49
- package/src/widgets/components/TreeWidget.tsx +0 -109
- package/src/widgets/components/index.ts +0 -30
- package/src/widgets/components/register.ts +0 -93
- package/src/widgets/components/table/CellRenderers.tsx +0 -83
- package/src/widgets/components/table/TablePagination.tsx +0 -45
- package/src/widgets/components/table/TableToolbar.tsx +0 -285
- package/src/widgets/components/table/filter-operators.ts +0 -134
- package/src/widgets/components/table/index.ts +0 -11
- package/src/widgets/condition/evaluator.ts +0 -57
- package/src/widgets/condition/index.ts +0 -1
- package/src/widgets/context/builder.ts +0 -99
- package/src/widgets/context/index.ts +0 -8
- package/src/widgets/context/types.ts +0 -37
- package/src/widgets/data/index.ts +0 -5
- package/src/widgets/data/useModelQuery.ts +0 -116
- package/src/widgets/data/useModelRecord.ts +0 -37
- package/src/widgets/expression/evaluator.ts +0 -100
- package/src/widgets/expression/functions.ts +0 -131
- package/src/widgets/expression/index.ts +0 -13
- package/src/widgets/expression/parser.ts +0 -229
- package/src/widgets/expression/types.ts +0 -45
- package/src/widgets/form/FormContext.ts +0 -29
- package/src/widgets/form/FormProvider.tsx +0 -84
- package/src/widgets/form/FormWidget.tsx +0 -42
- package/src/widgets/form/index.ts +0 -4
- package/src/widgets/form/useFormState.ts +0 -127
- package/src/widgets/form/useFormSubmit.ts +0 -90
- package/src/widgets/form/useFormValidation.ts +0 -62
- package/src/widgets/hooks/index.ts +0 -8
- package/src/widgets/hooks/useAction.ts +0 -83
- package/src/widgets/hooks/useBind.ts +0 -34
- package/src/widgets/hooks/useCondition.ts +0 -21
- package/src/widgets/hooks/useDataQuery.ts +0 -48
- package/src/widgets/hooks/useExpression.ts +0 -14
- package/src/widgets/hooks/usePageState.ts +0 -21
- package/src/widgets/hooks/useSurfaceContext.ts +0 -11
- package/src/widgets/hooks/useWidgetContext.ts +0 -14
- package/src/widgets/index.ts +0 -80
- package/src/widgets/lib/layout-props.ts +0 -135
- package/src/widgets/reactivity/index.ts +0 -11
- package/src/widgets/reactivity/tracker.ts +0 -139
- package/src/widgets/reactivity/variables.ts +0 -213
- package/src/widgets/registry.ts +0 -41
- package/src/widgets/renderer/SlotRenderer.tsx +0 -47
- package/src/widgets/renderer/WidgetRenderer.tsx +0 -191
- package/src/widgets/renderer/index.ts +0 -4
- package/src/widgets/shell/WidgetSlotRenderer.tsx +0 -73
- package/src/widgets/shell/index.ts +0 -4
- package/src/widgets/shell/useActionHandlers.ts +0 -170
- package/src/widgets/state/index.ts +0 -2
- package/src/widgets/state/store.ts +0 -96
- package/src/widgets/types.ts +0 -28
- package/src/widgets/validation/index.ts +0 -2
- package/src/widgets/validation/validator.ts +0 -140
- package/tsconfig.json +0 -27
- package/tsconfig.tsbuildinfo +0 -1
- package/vite.config.ts +0 -21
- package/vitest.config.ts +0 -16
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { useCallback, useMemo } from 'react';
|
|
2
|
-
import { useModelMeta } from '../../data/useModelMeta.js';
|
|
3
|
-
import type { FieldMeta as BootFieldMeta } from '@rangka/shared';
|
|
4
|
-
|
|
5
|
-
export interface UseFormValidationResult {
|
|
6
|
-
validateField(field: string, value: unknown): string | undefined;
|
|
7
|
-
validateAll(values: Record<string, unknown>): Record<string, string>;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function useFormValidation(model: string): UseFormValidationResult {
|
|
11
|
-
const { modelMeta } = useModelMeta(model);
|
|
12
|
-
|
|
13
|
-
const fieldMap = useMemo(() => {
|
|
14
|
-
if (!modelMeta) return new Map<string, BootFieldMeta>();
|
|
15
|
-
const map = new Map<string, BootFieldMeta>();
|
|
16
|
-
for (const field of modelMeta.fields) {
|
|
17
|
-
map.set(field.name, field);
|
|
18
|
-
}
|
|
19
|
-
return map;
|
|
20
|
-
}, [modelMeta]);
|
|
21
|
-
|
|
22
|
-
const validateField = useCallback(
|
|
23
|
-
(field: string, value: unknown): string | undefined => {
|
|
24
|
-
const meta = fieldMap.get(field);
|
|
25
|
-
if (!meta) return undefined;
|
|
26
|
-
|
|
27
|
-
if (meta.required && isEmpty(value)) {
|
|
28
|
-
return `${meta.label ?? field} is required`;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (meta.type === 'enum' && meta.options && value != null && value !== '') {
|
|
32
|
-
if (!meta.options.includes(String(value))) {
|
|
33
|
-
return `${meta.label ?? field} must be one of: ${meta.options.join(', ')}`;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return undefined;
|
|
38
|
-
},
|
|
39
|
-
[fieldMap],
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
const validateAll = useCallback(
|
|
43
|
-
(values: Record<string, unknown>): Record<string, string> => {
|
|
44
|
-
const errors: Record<string, string> = {};
|
|
45
|
-
for (const [name, meta] of fieldMap) {
|
|
46
|
-
if (meta.relationship) continue;
|
|
47
|
-
const error = validateField(name, values[name]);
|
|
48
|
-
if (error) errors[name] = error;
|
|
49
|
-
}
|
|
50
|
-
return errors;
|
|
51
|
-
},
|
|
52
|
-
[fieldMap, validateField],
|
|
53
|
-
);
|
|
54
|
-
|
|
55
|
-
return { validateField, validateAll };
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function isEmpty(value: unknown): boolean {
|
|
59
|
-
if (value === null || value === undefined) return true;
|
|
60
|
-
if (typeof value === 'string' && value.trim() === '') return true;
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { useWidgetContext, WidgetContextProvider } from './useWidgetContext.js';
|
|
2
|
-
export { usePageState, useStateVersion, PageStateProvider } from './usePageState.js';
|
|
3
|
-
export { useBind } from './useBind.js';
|
|
4
|
-
export { useExpression } from './useExpression.js';
|
|
5
|
-
export { useCondition } from './useCondition.js';
|
|
6
|
-
export { useAction, useTriggerHandlers } from './useAction.js';
|
|
7
|
-
export { useDataQuery } from './useDataQuery.js';
|
|
8
|
-
export type { DataQueryState } from './useDataQuery.js';
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { useCallback, useMemo, useRef } from 'react';
|
|
2
|
-
import { useWidgetContext } from './useWidgetContext.js';
|
|
3
|
-
import { usePageState } from './usePageState.js';
|
|
4
|
-
import { useFormContext } from '../form/FormContext.js';
|
|
5
|
-
import { dispatch } from '../action/dispatcher.js';
|
|
6
|
-
import type { WidgetAction } from '@rangka/shared';
|
|
7
|
-
import type { ActionHandlers } from '../action/dispatcher.js';
|
|
8
|
-
|
|
9
|
-
export function useAction(handlers: ActionHandlers) {
|
|
10
|
-
const ctx = useWidgetContext();
|
|
11
|
-
const state = usePageState();
|
|
12
|
-
const form = useFormContext();
|
|
13
|
-
|
|
14
|
-
const mergedHandlers = useMemo<ActionHandlers>(() => {
|
|
15
|
-
if (!form) return handlers;
|
|
16
|
-
return {
|
|
17
|
-
...handlers,
|
|
18
|
-
formSubmit: form.submit,
|
|
19
|
-
formReset: form.reset,
|
|
20
|
-
};
|
|
21
|
-
}, [handlers, form]);
|
|
22
|
-
|
|
23
|
-
const fire = useCallback(
|
|
24
|
-
async (action: WidgetAction) => {
|
|
25
|
-
await dispatch(action, { widgetContext: ctx, state }, mergedHandlers);
|
|
26
|
-
},
|
|
27
|
-
[ctx, state, mergedHandlers],
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
return useMemo(() => ({ fire }), [fire]);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function useTriggerHandlers(
|
|
34
|
-
triggers: Record<string, WidgetAction | WidgetAction[]> | undefined,
|
|
35
|
-
handlers: ActionHandlers,
|
|
36
|
-
boundField?: string,
|
|
37
|
-
): Record<string, (...args: unknown[]) => void> {
|
|
38
|
-
const ctx = useWidgetContext();
|
|
39
|
-
const state = usePageState();
|
|
40
|
-
const form = useFormContext();
|
|
41
|
-
const ctxRef = useRef(ctx);
|
|
42
|
-
ctxRef.current = ctx;
|
|
43
|
-
|
|
44
|
-
const mergedHandlers = useMemo<ActionHandlers>(() => {
|
|
45
|
-
if (!form) return handlers;
|
|
46
|
-
return {
|
|
47
|
-
...handlers,
|
|
48
|
-
formSubmit: form.submit,
|
|
49
|
-
formReset: form.reset,
|
|
50
|
-
};
|
|
51
|
-
}, [handlers, form]);
|
|
52
|
-
|
|
53
|
-
return useMemo(() => {
|
|
54
|
-
if (!triggers) return {};
|
|
55
|
-
const result: Record<string, (...args: unknown[]) => void> = {};
|
|
56
|
-
for (const [trigger, actionOrActions] of Object.entries(triggers)) {
|
|
57
|
-
result[trigger] = async (...args: unknown[]) => {
|
|
58
|
-
const actions = Array.isArray(actionOrActions) ? actionOrActions : [actionOrActions];
|
|
59
|
-
const currentCtx = ctxRef.current;
|
|
60
|
-
let widgetContext = currentCtx;
|
|
61
|
-
if (args.length > 0 && boundField) {
|
|
62
|
-
widgetContext = {
|
|
63
|
-
...currentCtx,
|
|
64
|
-
record: { ...currentCtx.record, [boundField]: args[0] },
|
|
65
|
-
};
|
|
66
|
-
} else if (args.length > 0 && typeof args[0] === 'object' && args[0] !== null) {
|
|
67
|
-
widgetContext = {
|
|
68
|
-
...currentCtx,
|
|
69
|
-
record: { ...currentCtx.record, ...(args[0] as Record<string, unknown>) },
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
try {
|
|
73
|
-
for (const action of actions) {
|
|
74
|
-
await dispatch(action, { widgetContext, state }, mergedHandlers);
|
|
75
|
-
}
|
|
76
|
-
} catch {
|
|
77
|
-
// Action errors are handled by onError callbacks in the action tree.
|
|
78
|
-
}
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return result;
|
|
82
|
-
}, [triggers, state, mergedHandlers, boundField]);
|
|
83
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useWidgetContext } from './useWidgetContext.js';
|
|
3
|
-
import { usePageState, useStateVersion } from './usePageState.js';
|
|
4
|
-
import { useFormContext } from '../form/FormContext.js';
|
|
5
|
-
import { resolveBinding } from '../binding/resolver.js';
|
|
6
|
-
import type { WidgetBinding } from '@rangka/shared';
|
|
7
|
-
import type { BindingResult, FieldMeta } from '../binding/resolver.js';
|
|
8
|
-
|
|
9
|
-
export function useBind(
|
|
10
|
-
bind: WidgetBinding | undefined,
|
|
11
|
-
fieldMeta?: Record<string, FieldMeta>,
|
|
12
|
-
setValue?: (field: string, val: unknown) => void,
|
|
13
|
-
): BindingResult | null {
|
|
14
|
-
const ctx = useWidgetContext();
|
|
15
|
-
const state = usePageState();
|
|
16
|
-
const stateVersion = useStateVersion();
|
|
17
|
-
const form = useFormContext();
|
|
18
|
-
|
|
19
|
-
return useMemo(() => {
|
|
20
|
-
const result = resolveBinding(bind, ctx, fieldMeta, setValue, state);
|
|
21
|
-
if (!result || !bind?.field || !form) return result;
|
|
22
|
-
|
|
23
|
-
const error = form.getError(bind.field);
|
|
24
|
-
return {
|
|
25
|
-
value: form.getValue(bind.field),
|
|
26
|
-
setValue: (val: unknown) => {
|
|
27
|
-
form.setValue(bind.field!, val);
|
|
28
|
-
form.setTouched(bind.field!);
|
|
29
|
-
},
|
|
30
|
-
meta: result.meta ?? form.getFieldMeta(bind.field),
|
|
31
|
-
error,
|
|
32
|
-
};
|
|
33
|
-
}, [bind, ctx, fieldMeta, setValue, state, stateVersion, form, form?.errors, form?.touched]);
|
|
34
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useWidgetContext } from './useWidgetContext.js';
|
|
3
|
-
import { usePageState, useStateVersion } from './usePageState.js';
|
|
4
|
-
import { evaluateConditions } from '../condition/index.js';
|
|
5
|
-
import { flattenContext } from '../context/types.js';
|
|
6
|
-
import type { Condition } from '@rangka/shared';
|
|
7
|
-
|
|
8
|
-
export function useCondition(conditions: Condition | Condition[] | undefined): boolean {
|
|
9
|
-
const ctx = useWidgetContext();
|
|
10
|
-
const state = usePageState();
|
|
11
|
-
const stateVersion = useStateVersion();
|
|
12
|
-
return useMemo(() => {
|
|
13
|
-
if (!conditions) return true;
|
|
14
|
-
const flat = flattenContext(ctx);
|
|
15
|
-
const merged: Record<string, unknown> = {
|
|
16
|
-
...flat,
|
|
17
|
-
$state: Object.fromEntries(state.keys().map((k) => [k, state.get(k)])),
|
|
18
|
-
};
|
|
19
|
-
return evaluateConditions(conditions, merged);
|
|
20
|
-
}, [conditions, ctx, state, stateVersion]);
|
|
21
|
-
}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { usePageState, useStateVersion } from './usePageState.js';
|
|
3
|
-
import {
|
|
4
|
-
getFiltersForModel,
|
|
5
|
-
getSortForModel,
|
|
6
|
-
getPageForModel,
|
|
7
|
-
getSearchForModel,
|
|
8
|
-
type ParsedFilter,
|
|
9
|
-
type SortEntry,
|
|
10
|
-
} from '../reactivity/variables.js';
|
|
11
|
-
|
|
12
|
-
export interface DataQueryState {
|
|
13
|
-
filters: ParsedFilter[];
|
|
14
|
-
sort: SortEntry[] | null;
|
|
15
|
-
page: number | null;
|
|
16
|
-
search: string | null;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Hook that reads the current $filter, $sort, and $page reactive variables
|
|
21
|
-
* for a given model from the page state store.
|
|
22
|
-
*
|
|
23
|
-
* Widgets like `table` and `data` (collection mode) use this to determine
|
|
24
|
-
* what query params to send when fetching data.
|
|
25
|
-
*
|
|
26
|
-
* Re-renders whenever any value in the store changes (same granularity as
|
|
27
|
-
* other widget hooks that use useStateVersion).
|
|
28
|
-
*/
|
|
29
|
-
export function useDataQuery(model: string): DataQueryState {
|
|
30
|
-
const store = usePageState();
|
|
31
|
-
// Subscribe to version changes so we re-render when any store value changes
|
|
32
|
-
const version = useStateVersion();
|
|
33
|
-
|
|
34
|
-
return useMemo(() => {
|
|
35
|
-
// Build a Map view of the store for the helper functions
|
|
36
|
-
const stateMap = new Map<string, unknown>();
|
|
37
|
-
for (const key of store.keys()) {
|
|
38
|
-
stateMap.set(key, store.get(key));
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return {
|
|
42
|
-
filters: getFiltersForModel(stateMap, model),
|
|
43
|
-
sort: getSortForModel(stateMap, model),
|
|
44
|
-
page: getPageForModel(stateMap, model),
|
|
45
|
-
search: getSearchForModel(stateMap, model),
|
|
46
|
-
};
|
|
47
|
-
}, [store, model, version]);
|
|
48
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react';
|
|
2
|
-
import { useWidgetContext } from './useWidgetContext.js';
|
|
3
|
-
import { parse, evaluate } from '../expression/index.js';
|
|
4
|
-
import { flattenContext } from '../context/types.js';
|
|
5
|
-
|
|
6
|
-
export function useExpression(expression: string | undefined): unknown {
|
|
7
|
-
const ctx = useWidgetContext();
|
|
8
|
-
return useMemo(() => {
|
|
9
|
-
if (!expression) return undefined;
|
|
10
|
-
const flat = flattenContext(ctx);
|
|
11
|
-
const ast = parse(expression);
|
|
12
|
-
return evaluate(ast, flat);
|
|
13
|
-
}, [expression, ctx]);
|
|
14
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext, useSyncExternalStore, useCallback } from 'react';
|
|
2
|
-
import { StateStore } from '../state/store.js';
|
|
3
|
-
|
|
4
|
-
const PageStateContext = createContext<StateStore | null>(null);
|
|
5
|
-
|
|
6
|
-
export const PageStateProvider = PageStateContext.Provider;
|
|
7
|
-
|
|
8
|
-
export function usePageState() {
|
|
9
|
-
const store = useContext(PageStateContext);
|
|
10
|
-
if (!store) {
|
|
11
|
-
throw new Error('usePageState must be used within a PageStateProvider');
|
|
12
|
-
}
|
|
13
|
-
return store;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export function useStateVersion(): number {
|
|
17
|
-
const store = usePageState();
|
|
18
|
-
const subscribe = useCallback((cb: () => void) => store.onchange(cb), [store]);
|
|
19
|
-
const getSnapshot = useCallback(() => store.getVersion(), [store]);
|
|
20
|
-
return useSyncExternalStore(subscribe, getSnapshot);
|
|
21
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from 'react';
|
|
2
|
-
|
|
3
|
-
type SurfaceType = 'page' | 'card';
|
|
4
|
-
|
|
5
|
-
const SurfaceContext = createContext<SurfaceType>('page');
|
|
6
|
-
|
|
7
|
-
export const SurfaceProvider = SurfaceContext.Provider;
|
|
8
|
-
|
|
9
|
-
export function useSurfaceContext(): SurfaceType {
|
|
10
|
-
return useContext(SurfaceContext);
|
|
11
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { createContext, useContext } from 'react';
|
|
2
|
-
import type { WidgetContext } from '../context/types.js';
|
|
3
|
-
|
|
4
|
-
const WidgetContextReact = createContext<WidgetContext | null>(null);
|
|
5
|
-
|
|
6
|
-
export const WidgetContextProvider = WidgetContextReact.Provider;
|
|
7
|
-
|
|
8
|
-
export function useWidgetContext(): WidgetContext {
|
|
9
|
-
const ctx = useContext(WidgetContextReact);
|
|
10
|
-
if (!ctx) {
|
|
11
|
-
throw new Error('useWidgetContext must be used within a WidgetContextProvider');
|
|
12
|
-
}
|
|
13
|
-
return ctx;
|
|
14
|
-
}
|
package/src/widgets/index.ts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
export { parse, evaluate, functions } from './expression/index.js';
|
|
2
|
-
export type { AstNode, EvalContext } from './expression/index.js';
|
|
3
|
-
|
|
4
|
-
export { evaluateCondition, evaluateConditions } from './condition/index.js';
|
|
5
|
-
|
|
6
|
-
export { StateStore } from './state/index.js';
|
|
7
|
-
export type { Subscriber } from './state/index.js';
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
buildContext,
|
|
11
|
-
buildRowContext,
|
|
12
|
-
createRootContext,
|
|
13
|
-
resolveContextValue,
|
|
14
|
-
getRootContext,
|
|
15
|
-
flattenContext,
|
|
16
|
-
} from './context/index.js';
|
|
17
|
-
export type { WidgetContext } from './context/index.js';
|
|
18
|
-
|
|
19
|
-
export { resolveBinding } from './binding/index.js';
|
|
20
|
-
export type { BindingResult, FieldMeta } from './binding/index.js';
|
|
21
|
-
|
|
22
|
-
export { dispatch, resolveExpressionValue } from './action/index.js';
|
|
23
|
-
export type { ActionContext, ActionHandlers } from './action/index.js';
|
|
24
|
-
|
|
25
|
-
export { buildDependencyMap, getAffectedWidgets } from './reactivity/index.js';
|
|
26
|
-
export type { DependencyMap } from './reactivity/index.js';
|
|
27
|
-
export {
|
|
28
|
-
parseFilterKey,
|
|
29
|
-
getFiltersForModel,
|
|
30
|
-
getSortForModel,
|
|
31
|
-
getPageForModel,
|
|
32
|
-
isReactiveVariableKey,
|
|
33
|
-
getModelFromKey,
|
|
34
|
-
} from './reactivity/index.js';
|
|
35
|
-
export type {
|
|
36
|
-
FilterOperator,
|
|
37
|
-
ParsedFilterKey,
|
|
38
|
-
ParsedFilter,
|
|
39
|
-
SortEntry,
|
|
40
|
-
} from './reactivity/index.js';
|
|
41
|
-
|
|
42
|
-
export { validateWidgetTree } from './validation/index.js';
|
|
43
|
-
export type { ValidationError } from './validation/index.js';
|
|
44
|
-
|
|
45
|
-
export {
|
|
46
|
-
registerWidget,
|
|
47
|
-
getWidget,
|
|
48
|
-
getWidgetMeta,
|
|
49
|
-
getAllWidgetMeta,
|
|
50
|
-
getWidgetRegistry,
|
|
51
|
-
clearWidgetRegistry,
|
|
52
|
-
} from './registry.js';
|
|
53
|
-
export type { WidgetRegistryEntry } from './registry.js';
|
|
54
|
-
export type { WidgetProps } from './types.js';
|
|
55
|
-
|
|
56
|
-
export { WidgetRenderer } from './renderer/index.js';
|
|
57
|
-
export type { WidgetRendererProps } from './renderer/index.js';
|
|
58
|
-
export { SlotRenderer } from './renderer/index.js';
|
|
59
|
-
export type { SlotRendererProps } from './renderer/index.js';
|
|
60
|
-
|
|
61
|
-
export { useWidgetContext, WidgetContextProvider } from './hooks/index.js';
|
|
62
|
-
export { usePageState, PageStateProvider } from './hooks/index.js';
|
|
63
|
-
export { useBind } from './hooks/index.js';
|
|
64
|
-
export { useExpression } from './hooks/index.js';
|
|
65
|
-
export { useCondition } from './hooks/index.js';
|
|
66
|
-
export { useAction, useTriggerHandlers } from './hooks/index.js';
|
|
67
|
-
export { useDataQuery } from './hooks/index.js';
|
|
68
|
-
export type { DataQueryState } from './hooks/index.js';
|
|
69
|
-
|
|
70
|
-
export { registerBuiltInWidgets } from './components/register.js';
|
|
71
|
-
export { ButtonWidget } from './components/index.js';
|
|
72
|
-
export { InputWidget } from './components/index.js';
|
|
73
|
-
export { TextWidget } from './components/index.js';
|
|
74
|
-
export { BadgeWidget } from './components/index.js';
|
|
75
|
-
export { IconWidget } from './components/index.js';
|
|
76
|
-
export { ImageWidget } from './components/index.js';
|
|
77
|
-
export { GroupWidget } from './components/index.js';
|
|
78
|
-
export { SectionWidget } from './components/index.js';
|
|
79
|
-
export { DividerWidget } from './components/index.js';
|
|
80
|
-
export { SpacerWidget } from './components/index.js';
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import type { LayoutProps, SpacingToken } from '@rangka/shared';
|
|
2
|
-
|
|
3
|
-
const LAYOUT_PROP_KEYS: readonly string[] = [
|
|
4
|
-
'flex',
|
|
5
|
-
'span',
|
|
6
|
-
'rowSpan',
|
|
7
|
-
'align',
|
|
8
|
-
'width',
|
|
9
|
-
'height',
|
|
10
|
-
'minWidth',
|
|
11
|
-
'maxWidth',
|
|
12
|
-
'minHeight',
|
|
13
|
-
'maxHeight',
|
|
14
|
-
'scroll',
|
|
15
|
-
'padding',
|
|
16
|
-
'paddingX',
|
|
17
|
-
'paddingY',
|
|
18
|
-
'margin',
|
|
19
|
-
'marginX',
|
|
20
|
-
'marginY',
|
|
21
|
-
'hidden',
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
const SPACING_MAP: Record<SpacingToken, string> = {
|
|
25
|
-
none: '0',
|
|
26
|
-
xs: '1',
|
|
27
|
-
sm: '2',
|
|
28
|
-
md: '4',
|
|
29
|
-
lg: '6',
|
|
30
|
-
xl: '8',
|
|
31
|
-
'2xl': '12',
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
function spacingClass(prefix: string, token: SpacingToken): string {
|
|
35
|
-
return `${prefix}-${SPACING_MAP[token]}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function extractLayoutProps(props: Record<string, unknown>): {
|
|
39
|
-
layoutProps: LayoutProps;
|
|
40
|
-
widgetProps: Record<string, unknown>;
|
|
41
|
-
} {
|
|
42
|
-
const layoutProps: Record<string, unknown> = {};
|
|
43
|
-
const widgetProps: Record<string, unknown> = {};
|
|
44
|
-
|
|
45
|
-
for (const [key, value] of Object.entries(props)) {
|
|
46
|
-
if (LAYOUT_PROP_KEYS.includes(key)) {
|
|
47
|
-
layoutProps[key] = value;
|
|
48
|
-
} else {
|
|
49
|
-
widgetProps[key] = value;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return { layoutProps: layoutProps as LayoutProps, widgetProps };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function hasLayoutProps(props: Record<string, unknown>): boolean {
|
|
57
|
-
return Object.keys(props).some((key) => LAYOUT_PROP_KEYS.includes(key));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export function resolveLayoutClasses(layout: LayoutProps): string {
|
|
61
|
-
const classes: string[] = [];
|
|
62
|
-
|
|
63
|
-
// Flex
|
|
64
|
-
if (layout.flex !== undefined) {
|
|
65
|
-
if (layout.flex === 1) {
|
|
66
|
-
classes.push('flex-1');
|
|
67
|
-
} else if (typeof layout.flex === 'number') {
|
|
68
|
-
classes.push(`flex-[${layout.flex}]`);
|
|
69
|
-
} else if (typeof layout.flex === 'string') {
|
|
70
|
-
classes.push(`flex-[${layout.flex.replace(/ /g, '_')}]`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Grid span
|
|
75
|
-
if (layout.span !== undefined) {
|
|
76
|
-
classes.push(`col-span-${layout.span}`);
|
|
77
|
-
}
|
|
78
|
-
if (layout.rowSpan !== undefined) {
|
|
79
|
-
classes.push(`row-span-${layout.rowSpan}`);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Self-alignment
|
|
83
|
-
if (layout.align) {
|
|
84
|
-
const alignMap: Record<string, string> = {
|
|
85
|
-
start: 'self-start',
|
|
86
|
-
center: 'self-center',
|
|
87
|
-
end: 'self-end',
|
|
88
|
-
stretch: 'self-stretch',
|
|
89
|
-
};
|
|
90
|
-
classes.push(alignMap[layout.align] ?? '');
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Dimensions
|
|
94
|
-
if (layout.width) {
|
|
95
|
-
if (layout.width === '100%') classes.push('w-full');
|
|
96
|
-
else if (layout.width === 'auto') classes.push('w-auto');
|
|
97
|
-
else classes.push(`w-[${layout.width}]`);
|
|
98
|
-
}
|
|
99
|
-
if (layout.height) {
|
|
100
|
-
if (layout.height === '100%') classes.push('h-full');
|
|
101
|
-
else if (layout.height === 'auto') classes.push('h-auto');
|
|
102
|
-
else classes.push(`h-[${layout.height}]`);
|
|
103
|
-
}
|
|
104
|
-
if (layout.minWidth) classes.push(`min-w-[${layout.minWidth}]`);
|
|
105
|
-
if (layout.maxWidth) classes.push(`max-w-[${layout.maxWidth}]`);
|
|
106
|
-
if (layout.minHeight) classes.push(`min-h-[${layout.minHeight}]`);
|
|
107
|
-
if (layout.maxHeight) classes.push(`max-h-[${layout.maxHeight}]`);
|
|
108
|
-
|
|
109
|
-
// Scroll
|
|
110
|
-
if (layout.scroll) {
|
|
111
|
-
const scrollMap: Record<string, string> = {
|
|
112
|
-
auto: 'overflow-auto',
|
|
113
|
-
vertical: 'overflow-y-auto',
|
|
114
|
-
horizontal: 'overflow-x-auto',
|
|
115
|
-
};
|
|
116
|
-
classes.push(scrollMap[layout.scroll] ?? '');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Padding
|
|
120
|
-
if (layout.padding) classes.push(spacingClass('p', layout.padding));
|
|
121
|
-
if (layout.paddingX) classes.push(spacingClass('px', layout.paddingX));
|
|
122
|
-
if (layout.paddingY) classes.push(spacingClass('py', layout.paddingY));
|
|
123
|
-
|
|
124
|
-
// Margin
|
|
125
|
-
if (layout.margin) classes.push(spacingClass('m', layout.margin));
|
|
126
|
-
if (layout.marginX) classes.push(spacingClass('mx', layout.marginX));
|
|
127
|
-
if (layout.marginY) classes.push(spacingClass('my', layout.marginY));
|
|
128
|
-
|
|
129
|
-
// Hidden
|
|
130
|
-
if (layout.hidden) {
|
|
131
|
-
classes.push(`${layout.hidden}:hidden`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return classes.filter(Boolean).join(' ');
|
|
135
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export { buildDependencyMap, getAffectedWidgets } from './tracker.js';
|
|
2
|
-
export type { DependencyMap } from './tracker.js';
|
|
3
|
-
export {
|
|
4
|
-
parseFilterKey,
|
|
5
|
-
getFiltersForModel,
|
|
6
|
-
getSortForModel,
|
|
7
|
-
getPageForModel,
|
|
8
|
-
isReactiveVariableKey,
|
|
9
|
-
getModelFromKey,
|
|
10
|
-
} from './variables.js';
|
|
11
|
-
export type { FilterOperator, ParsedFilterKey, ParsedFilter, SortEntry } from './variables.js';
|