@magicvr/schema-ui-renderer 0.3.0 → 0.3.2

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.
Files changed (38) hide show
  1. package/index.js +17 -17
  2. package/package.json +6 -6
  3. package/components/account-session-toolbar.d.ts +0 -2
  4. package/components/activity-export.d.ts +0 -2
  5. package/components/cron-preview.d.ts +0 -2
  6. package/components/data-permission-scopes.d.ts +0 -2
  7. package/components/data-table.d.ts +0 -43
  8. package/components/email-identity.d.ts +0 -2
  9. package/components/force-password-change.d.ts +0 -1
  10. package/components/import-template-download.d.ts +0 -2
  11. package/components/invite-accept.d.ts +0 -6
  12. package/components/invite-issue-card.d.ts +0 -7
  13. package/components/invite-resend-dialog.d.ts +0 -9
  14. package/components/locale-switcher.d.ts +0 -23
  15. package/components/mail-admin-tab.d.ts +0 -2
  16. package/components/mfa-manager.d.ts +0 -2
  17. package/components/monitoring-auto-refresh.d.ts +0 -2
  18. package/components/notification-center.d.ts +0 -2
  19. package/components/password-policy-tab.d.ts +0 -6
  20. package/components/qr-code.d.ts +0 -16
  21. package/components/theme-toggle.d.ts +0 -10
  22. package/components/timezone-switcher.d.ts +0 -16
  23. package/components/wallet-ensure.d.ts +0 -2
  24. package/renderer/confirm.d.ts +0 -17
  25. package/renderer/custom-components.d.ts +0 -14
  26. package/renderer/form-controls.d.ts +0 -45
  27. package/renderer/form-controls.types.d.ts +0 -135
  28. package/renderer/index.d.ts +0 -13
  29. package/renderer/modal.d.ts +0 -6
  30. package/renderer/permissions.d.ts +0 -53
  31. package/renderer/reaction-engine.d.ts +0 -92
  32. package/renderer/reaction-expression.d.ts +0 -74
  33. package/renderer/reactions.d.ts +0 -64
  34. package/renderer/render.d.ts +0 -194
  35. package/renderer/render.types.d.ts +0 -289
  36. package/renderer/resource.d.ts +0 -114
  37. package/renderer/row-action.d.ts +0 -28
  38. package/renderer/schema-table.d.ts +0 -90
@@ -1,92 +0,0 @@
1
- /**
2
- * Multi-round snapshot reaction engine (schema-ui-docs@2.7.0 · 02-reaction-expression.md §14).
3
- *
4
- * Implements the upstream conformance contract (`conformance/fixtures/reactions/cases.json`):
5
- * Snapshot → Evaluate → Commit → Next tick, with:
6
- * - per-field reactions [{ when, fulfill, otherwise }] (value/visible/required/disabled)
7
- * - observers evaluated against every round snapshot
8
- * - baselines + resetMissingOtherwise (condition false without otherwise → restore baseline;
9
- * explicit writes win over implicit baseline restores)
10
- * - externalUpdates applied between rounds
11
- * - deep-equal change detection (no commit / no next round on no-op writes)
12
- * - loop protection (REACTION_LOOP_LIMIT after maxRounds, default 10)
13
- * - MULTIPLE_VALUE_WRITES warnings (last write wins, deterministic order)
14
- */
15
- export interface ReactionRuleInput {
16
- when: string;
17
- fulfill?: Record<string, unknown>;
18
- otherwise?: Record<string, unknown>;
19
- }
20
- export interface FieldReactionInput {
21
- field: string;
22
- reactions: ReactionRuleInput[];
23
- }
24
- export interface ReactionObserverInput {
25
- id: string;
26
- when: string;
27
- }
28
- export interface ExternalUpdateInput {
29
- afterRound: number;
30
- values: Record<string, unknown>;
31
- }
32
- export interface ReactionEngineInput {
33
- initialValues: Record<string, unknown>;
34
- fields?: FieldReactionInput[];
35
- observers?: ReactionObserverInput[];
36
- baselines?: Record<string, unknown>;
37
- resetMissingOtherwise?: boolean;
38
- externalUpdates?: ExternalUpdateInput[];
39
- maxRounds?: number;
40
- }
41
- export interface ReactionRound {
42
- round: number;
43
- snapshot: Record<string, unknown>;
44
- observations: Record<string, boolean>;
45
- commits: Array<{
46
- field: string;
47
- value: unknown;
48
- }>;
49
- }
50
- export interface MultipleValueWritesWarning {
51
- code: "MULTIPLE_VALUE_WRITES";
52
- field: string;
53
- count: number;
54
- }
55
- export interface ReactionEngineOk {
56
- ok: true;
57
- values: Record<string, unknown>;
58
- rounds: ReactionRound[];
59
- warnings: MultipleValueWritesWarning[];
60
- }
61
- export interface ReactionEngineLoopError {
62
- ok: false;
63
- code: "REACTION_LOOP_LIMIT";
64
- maxRounds: number;
65
- values: Record<string, unknown>;
66
- roundCount: number;
67
- dependencyFields: string[];
68
- }
69
- export type ReactionEngineResult = ReactionEngineOk | ReactionEngineLoopError;
70
- /** Per-field control state after convergence (renderer integration). */
71
- export interface ReactionFieldState {
72
- visible?: boolean;
73
- required?: boolean;
74
- disabled?: boolean;
75
- }
76
- export interface ReactionEngineDetailed {
77
- result: ReactionEngineResult;
78
- fieldStates: Record<string, ReactionFieldState>;
79
- }
80
- export declare const DEFAULT_MAX_ROUNDS = 10;
81
- /**
82
- * Runs the multi-round engine.
83
- *
84
- * A field's committed `value` only lands in `commits` when it deep-differs
85
- * from the snapshot value; a no-op write neither commits nor schedules the
86
- * next round. Rounds stop when no committed field is a dependency of any
87
- * expression (reaction when or observer when).
88
- */
89
- export declare function runReactionEngine(input: ReactionEngineInput): ReactionEngineResult;
90
- /** Engine + per-field control state (visible/required/disabled/value) from
91
- * the final round — used by the Renderer's form integration. */
92
- export declare function runReactionEngineDetailed(input: ReactionEngineInput): ReactionEngineDetailed;
@@ -1,74 +0,0 @@
1
- /**
2
- * Full protocol expression engine (schema-ui-docs@2.7.0 · docs/02-reaction-expression.md).
3
- *
4
- * Whitelisted grammar (no eval / new Function):
5
- * - namespaces: $deps.<field>, $self, $context.user.* / $context.features.*
6
- * - operators: == != > >= < <= contains && || !
7
- * - grouping: ( )
8
- * - literals: 'str' | "str" | number (int/float/exponent) | true | false | null
9
- *
10
- * Semantics (ADR-0016 / §7-§14):
11
- * - strict typing, no coercion: 1 == 1.0 true; 1 == '1' false; true == 1 false
12
- * - contains: array left operand, strict element equality; non-array → false
13
- * - string ordering by Unicode code points (not UTF-16 code units)
14
- * - undefined values compare as false (missing deps never throw)
15
- */
16
- export type ExprValue = string | number | boolean | null | ExprValue[] | {
17
- [key: string]: ExprValue;
18
- } | undefined;
19
- export interface ReactionEnv {
20
- /** $deps.<field> values (form field snapshot). */
21
- deps?: Record<string, unknown>;
22
- /** $self (current field value). */
23
- self?: unknown;
24
- /** $context.user.* / $context.features.* snapshots. */
25
- context?: Record<string, unknown>;
26
- }
27
- export type ParseError = {
28
- ok: false;
29
- code: "SYNTAX";
30
- message: string;
31
- } | {
32
- ok: false;
33
- code: "FORBIDDEN_VARIABLE";
34
- message: string;
35
- } | {
36
- ok: false;
37
- code: "UNSUPPORTED_OPERATOR";
38
- message: string;
39
- };
40
- export type ParsedExpr = {
41
- kind: "literal";
42
- value: ExprValue;
43
- } | {
44
- kind: "var";
45
- path: string[];
46
- } | {
47
- kind: "self";
48
- } | {
49
- kind: "not";
50
- operand: ParsedExpr;
51
- } | {
52
- kind: "and";
53
- left: ParsedExpr;
54
- right: ParsedExpr;
55
- } | {
56
- kind: "or";
57
- left: ParsedExpr;
58
- right: ParsedExpr;
59
- } | {
60
- kind: "compare";
61
- op: "==" | "!=" | ">" | ">=" | "<" | "<=" | "contains";
62
- left: ParsedExpr;
63
- right: ParsedExpr;
64
- };
65
- /** Parses a whitelisted expression; returns the AST or a typed error. */
66
- export declare function parseExpression(source: string): ParsedExpr | ParseError;
67
- /** Deep equality (arrays/objects by structure; scalars by strict identity). */
68
- export declare function deepEqual(left: unknown, right: unknown): boolean;
69
- /** Evaluates a whitelisted expression to a boolean; invalid input → false. */
70
- export declare function evaluateFullExpression(source: string, env: ReactionEnv): boolean;
71
- /** True when `source` parses under the full grammar. */
72
- export declare function isValidFullExpression(source: string): boolean;
73
- /** Extracts the $deps.<root> field names referenced by an expression. */
74
- export declare function expressionDependencyFields(source: string): string[];
@@ -1,64 +0,0 @@
1
- /**
2
- * R5 D-EXPR reaction surface (frozen Q: reactions operate on the $context
3
- * namespace only; no field-value triggers).
4
- *
5
- * A reaction is a `{ when, apply }` rule: `when` is a frozen $context
6
- * expression (evaluateExpression grammar), and `apply` turns a form control
7
- * state on/off when the expression holds. This is the renderer-level
8
- * equivalent of the navigation visibleWhen gate, applied to form fields.
9
- *
10
- * Fails closed: an unparseable `when` expression or an unknown apply target
11
- * keeps the field at its default state instead of mutating it silently.
12
- */
13
- export interface ReactionApply {
14
- fieldId: string;
15
- /** visible/disabled toggles are explicit booleans (no implicit flip). */
16
- visible?: boolean;
17
- disabled?: boolean;
18
- }
19
- export interface ReactionRule {
20
- id: string;
21
- when: string;
22
- apply: ReactionApply[];
23
- }
24
- export type ReactionErrorCode = "REACTION_EXPRESSION_INVALID" | "REACTION_APPLY_FIELD_UNKNOWN" | "REACTION_APPLY_INVALID";
25
- export interface ReactionError {
26
- code: ReactionErrorCode;
27
- path: string;
28
- message: string;
29
- }
30
- export interface FormControlState {
31
- visible: boolean;
32
- disabled: boolean;
33
- }
34
- export type FormControlStateMap = Record<string, FormControlState>;
35
- export interface ReactionEvaluation {
36
- state: FormControlStateMap;
37
- errors: ReactionError[];
38
- }
39
- /** Parses a raw reaction rule, fail-closed on malformed shapes. */
40
- export declare function parseReactionRule(value: unknown, path: string): ReactionRule | ReactionError;
41
- /**
42
- * Evaluates a reaction rule list against the frozen $context snapshot.
43
- * Unknown apply fieldIds fail closed (keep default) and are reported.
44
- */
45
- export declare function evaluateReactions(rules: ReactionRule[], context: Record<string, unknown>, fieldIds: string[]): ReactionEvaluation;
46
- /** Validates raw rules and returns parsed rules + fail-closed errors. */
47
- export declare function parseAndEvaluateReactions(rawRules: unknown, context: Record<string, unknown>, fieldIds: string[]): ReactionEvaluation;
48
- export interface FullReactionResult {
49
- /** True when the form declares upstream-shaped per-field reactions ($deps). */
50
- usesFullEngine: boolean;
51
- /** Per-field control state after convergence (visible/disabled). */
52
- state: FormControlStateMap;
53
- /** Value commits to merge into the form values (last-wins, convergent). */
54
- values: Record<string, unknown>;
55
- errors: ReactionError[];
56
- }
57
- /**
58
- * Resolves the full multi-round $deps reaction engine over a form's fields.
59
- *
60
- * Upstream shape (02-reaction-expression.md): each field node carries
61
- * `reactions: [{ when, fulfill, otherwise }]`. Returns the convergent control
62
- * state + value commits; malformed rules fail closed (reported, not applied).
63
- */
64
- export declare function resolveFullFormReactions(rawFields: unknown, values: Record<string, unknown>, baselines: Record<string, unknown>): FullReactionResult;
@@ -1,194 +0,0 @@
1
- import { type ComponentType, type ReactNode } from "react";
2
- import { type UploadableFile } from "@schema-ui/protocol/conformance/upload-orchestration";
3
- import { type FormControlField } from "@schema-ui/renderer/renderer/form-controls.types";
4
- import { type ResourceList, type ResourceQuery } from "@schema-ui/renderer/renderer/resource";
5
- import { type RenderActionButtonNode, type RenderChartNode, type RenderFormNode, type RenderPageDocument, type RenderStatCardNode, type RenderTableNode } from "@schema-ui/renderer/renderer/render.types";
6
- /**
7
- * R5 D-COMP minimal Renderer (resolve R4 F-002) + S4 Schema CRUD (GOAL-007).
8
- *
9
- * Dispatch layer: parses a page document, applies the frozen $context
10
- * reaction engine to form field state, and renders whitelisted node types
11
- * through the components in this directory. Unknown node types fail closed.
12
- *
13
- * S4 one-time completion (I-007-003 v0.2.2 §9): a SchemaCrudProvider owns the
14
- * cross-node state a Schema-driven CRUD page needs — selected row (feeds
15
- * recordView + edit-form prefill), per-table query (search form-to-query
16
- * binding), a reload token, the active modal, the pending delete confirm, and
17
- * a generic action executor that gates through the frozen `executeAction`
18
- * engine and constructs requests with the pinned conformance constructor
19
- * (`request-construction.ts`). Every page-level behaviour stays fixture-driven;
20
- * after this completion page behavior remains schema-owned; core fixtures and
21
- * module-owned schema packages can add pages without Renderer changes.
22
- *
23
- * Scope: the frozen §5 node whitelist — layout (grid/section/tabs),
24
- * data/action (text/table/recordView/actionButton) and form. The form control
25
- * whitelist itself is enforced by D-FORM (isWhitelistedFormControl /
26
- * checkFormCapabilities) via gateRenderFormFields. The default app path wires
27
- * a schema-driven table surface (SchemaTable, GOAL-004) as `tableRenderer`;
28
- * a table node dispatched without one fails closed with an observable note.
29
- *
30
- * A-002 F-002-002 (GOAL-009 S1): form submission is blocked while any
31
- * gate/reaction error is present — the submit button is disabled and
32
- * handleSubmit re-rejects before any request can be constructed.
33
- */
34
- export interface RendererComponentProps {
35
- document: RenderPageDocument;
36
- context: Record<string, unknown>;
37
- /** Renders a table node; provided by the example page that owns data. */
38
- tableRenderer?: (node: RenderTableNode) => ReactNode;
39
- /** Renders statCard/chart nodes (supportsData display, registry); defaults to built-ins. */
40
- dataRenderer?: (node: RenderStatCardNode | RenderChartNode) => ReactNode;
41
- /** Invoked when an actionButton node is activated. */
42
- onAction?: (node: RenderActionButtonNode) => void;
43
- /**
44
- * Session-internal navigation hook (ADR-0021 navigate actions; GOAL-015
45
- * F-001): the host pushes the target onto its own history/visit stack so
46
- * breadcrumbs survive. Falls back to window.location.assign when absent.
47
- */
48
- onNavigate?: (url: string) => void;
49
- /** Overrides the default FormControls component (keeps field wiring local). */
50
- formComponent?: ComponentType<{
51
- fields: FormControlField[];
52
- values: Record<string, unknown>;
53
- onChange: (id: string, value: unknown) => void;
54
- fieldDisabled?: (id: string) => boolean;
55
- onUpload?: (field: FormControlField, files: UploadableFile[]) => Promise<unknown>;
56
- /** W11 · U-01/U-02: auth-aware transport for dynamic option sources. */
57
- fetcher?: typeof fetch;
58
- }>;
59
- }
60
- export interface SchemaCrudFeedback {
61
- kind: "success" | "error";
62
- message: string;
63
- code?: string;
64
- /** VP-007 S4: catalog key for the frontend localization floor. */
65
- messageKey?: string;
66
- /** VP-007 S4: interpolation params for messageKey. */
67
- params?: Record<string, unknown>;
68
- }
69
- export interface SchemaCrudConfirm {
70
- actionRef: string;
71
- actionKey: string;
72
- row: Record<string, unknown>;
73
- requestMapping?: Record<string, unknown>;
74
- message: string;
75
- /** Batch trigger confirm (ADR-0022 D4/D5): carries the selection snapshot. */
76
- batch?: {
77
- tableId: string;
78
- selection: TableSelection;
79
- };
80
- /** Toolbar item batchMapping carried through confirm. */
81
- batchMapping?: Record<string, unknown>;
82
- }
83
- /** Selection snapshot (ADR-0022 D3): ordered keys + count. */
84
- export interface TableSelection {
85
- keys: unknown[];
86
- count: number;
87
- }
88
- export type ActionResult = {
89
- ok: true;
90
- fieldErrors?: Array<{
91
- field: string;
92
- reason: string;
93
- rowNumber?: number;
94
- }>;
95
- message?: string;
96
- messageKey?: string;
97
- } | {
98
- ok: false;
99
- code: string;
100
- message: string;
101
- messageKey?: string;
102
- params?: Record<string, unknown>;
103
- /** GOAL-014 D-002 §2: server field-level validation failures. */
104
- fieldErrors?: Array<{
105
- field: string;
106
- reason: string;
107
- rowNumber?: number;
108
- }>;
109
- };
110
- export interface SchemaCrudValue {
111
- selectedRow: Record<string, unknown> | null;
112
- selectRow: (row: Record<string, unknown> | null) => void;
113
- tableQuery: (id: string) => ResourceQuery | undefined;
114
- setTableQuery: (id: string, query: ResourceQuery) => void;
115
- reloadToken: number;
116
- reloadList: () => void;
117
- /**
118
- * Fetches a resource list through the page-level in-flight coalescer:
119
- * simultaneous consumers of the same URL share ONE network request (three
120
- * statCards + the wallet-ensure probe on one "我的钱包" visit merge into a
121
- * single GET /me). Requests are otherwise never memoized — every query,
122
- * reset or reload refetches — and reloadList drops the in-flight map so a
123
- * reload issued during a slow fetch starts its own fresh request.
124
- * `transport` is the caller's own transport (a directly injected fixture or
125
- * the auth fetcher); defaults to the provider's registered fetcher.
126
- */
127
- fetchList: (dataSource: string, query: ResourceQuery, extraQuery?: string, transport?: typeof fetch) => Promise<ResourceList>;
128
- /**
129
- * Targeted display-data refresh (W25): bumps the per-URL refresh token for
130
- * the standard display query of `dataSource` (statCard/chart consume it),
131
- * so a consumer can refetch ONE surface without a full-page reload wave.
132
- * Only applies to display nodes without route-param bindings (the standard
133
- * DISPLAY_LIST_QUERY shape); tables/misc surfaces keep their data until a
134
- * manual reload.
135
- */
136
- refreshList: (dataSource: string) => void;
137
- /** Current refresh token for a display dataSource (0 when untouched). */
138
- listRefreshToken: (dataSource: string) => number;
139
- activeModal: {
140
- actionRef: string;
141
- row: Record<string, unknown> | null;
142
- title: string;
143
- } | null;
144
- modalRow: Record<string, unknown> | null;
145
- openModal: (actionRef: string, row: Record<string, unknown> | null, title: string) => void;
146
- closeModal: () => void;
147
- pendingConfirm: SchemaCrudConfirm | null;
148
- requestConfirm: (confirm: SchemaCrudConfirm) => void;
149
- resolveConfirm: (confirmed: boolean) => Promise<void>;
150
- feedback: SchemaCrudFeedback | null;
151
- registerFetcher: (fetcher: typeof fetch) => void;
152
- /** The currently registered transport (globalThis.fetch until injected). */
153
- fetcher: typeof fetch;
154
- /** Runs a request action end-to-end (gate → construct → fetch → feedback/reload). */
155
- runRowAction: (actionRef: string, opts: RunRequestOptions) => Promise<ActionResult>;
156
- /** Dispatches a toolbar/row action entry: modal open, confirm, or request. */
157
- invokeAction: (item: Record<string, unknown>, row: Record<string, unknown> | null) => void;
158
- /** Dispatches a batch toolbar trigger (ADR-0022): gate → confirm → request. */
159
- invokeBatchAction: (item: Record<string, unknown>, tableId: string) => void;
160
- /** Upload control transport (ADR-0012): resolves action/actionRef → validates → uploads. */
161
- uploadFiles: (field: FormControlField, files: UploadableFile[]) => Promise<unknown>;
162
- /** Per-table selection state (keys + count; normalized by the table). */
163
- selection: (tableId: string) => TableSelection | undefined;
164
- setSelection: (tableId: string, keys: unknown[]) => void;
165
- clearSelection: (tableId: string) => void;
166
- /** Submits a default-mode form against its `submitAction`. */
167
- submitForm: (form: RenderFormNode, values: Record<string, unknown>) => Promise<ActionResult>;
168
- /** Binds a search-mode form's fields to its target table query. */
169
- searchFormSubmit: (form: RenderFormNode, values: Record<string, unknown>) => void;
170
- effectivePermission: (targetId: string) => boolean;
171
- /**
172
- * Current route snapshot (from the render context; App injects
173
- * route: {params, query}). Used for ADR-0039 dataSource bindings and
174
- * create-modal readOnly seeding instead of reading window.location.
175
- */
176
- route: {
177
- query: Record<string, string>;
178
- params: Record<string, string>;
179
- };
180
- }
181
- export interface RunRequestOptions {
182
- row?: Record<string, unknown> | null;
183
- formValues?: Record<string, unknown>;
184
- requestMapping?: Record<string, unknown>;
185
- gateTargetId?: string;
186
- confirmed?: boolean;
187
- }
188
- /** Page CRUD context consumed by custom components (rendered nodes). */
189
- export declare const SchemaCrudContext: import("react").Context<SchemaCrudValue | null>;
190
- /** Reads the page-level Schema CRUD provider (null when rendered bare). */
191
- export declare function useSchemaCrud(): SchemaCrudValue | null;
192
- export declare function RenderPage({ document, context, tableRenderer, dataFetcher, onAction, onNavigate, formComponent, }: RendererComponentProps & {
193
- dataFetcher?: typeof fetch;
194
- }): import("react").JSX.Element;