jsonisch 0.1.0 → 0.1.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.
- package/CHANGELOG.md +22 -0
- package/README.md +33 -14
- package/dist/{form-ref-D_xHSaqL.d.ts → form-ref-FEumWYOE.d.ts} +9 -1
- package/dist/{form-ref-BEri3JKv.js → form-ref-WEtlz2iK.js} +30 -4
- package/dist/{handle-submit-Dk7QW3_q.d.ts → handle-submit-AUrq5T7Y.d.ts} +1 -1
- package/dist/{handle-submit-CD3WY9gW.js → handle-submit-De-yR66a.js} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -4
- package/dist/plugin/index.d.ts +12 -3
- package/dist/plugin/index.js +2 -2
- package/dist/{plugin-Qka-vaO1.js → plugin-Bdw1RuiF.js} +2 -2
- package/dist/{plugin-BCsAE8RK.d.ts → plugin-CDzZKTHb.d.ts} +3 -3
- package/dist/react/index.d.ts +2 -2
- package/dist/react/index.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.1.2](https://github.com/andrew310/jsonisch/compare/v0.1.1...v0.1.2) (2026-09-08)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* derived keys absent from input projection; dist augmentations target public specifier ([#30](https://github.com/andrew310/jsonisch/issues/30)) ([7188b24](https://github.com/andrew310/jsonisch/commit/7188b248e2a0b717224d0c029cc88b2c71beba51)), closes [#28](https://github.com/andrew310/jsonisch/issues/28)
|
|
9
|
+
|
|
10
|
+
## [0.1.1](https://github.com/andrew310/jsonisch/compare/v0.1.0...v0.1.1) (2026-09-08)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **ci:** match plain vX.Y.Z tags — the changelog scanned all history ([#25](https://github.com/andrew310/jsonisch/issues/25)) ([207b2ef](https://github.com/andrew310/jsonisch/commit/207b2efd238c23cf9223ea72ae46de995d565d9e))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
|
|
20
|
+
* best-of-three names three real lineages ([#18](https://github.com/andrew310/jsonisch/issues/18)) ([fc6894e](https://github.com/andrew310/jsonisch/commit/fc6894e9149ee0e8fd02869a3c8bc67dfddc7d07))
|
|
21
|
+
* lineage section states what we actually studied ([#19](https://github.com/andrew310/jsonisch/issues/19)) ([3e70c2c](https://github.com/andrew310/jsonisch/commit/3e70c2c6c249fc599bc7ab61f09e79f5537e5a82))
|
|
22
|
+
* logo in the README ([#17](https://github.com/andrew310/jsonisch/issues/17)) ([0191401](https://github.com/andrew310/jsonisch/commit/0191401ca22c7410f9ec08061955540f63d0a406))
|
|
23
|
+
* the agent angle — a schema an LLM just wrote is a form ([#22](https://github.com/andrew310/jsonisch/issues/22)) ([dd7c1d4](https://github.com/andrew310/jsonisch/commit/dd7c1d450500f8493f110493038519ea4a6a7dbb))
|
|
24
|
+
|
|
3
25
|
## 0.1.0
|
|
4
26
|
|
|
5
27
|
First public release. Extracted from the RWA platform with history intact.
|
package/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/andrew310/jsonisch/main/assets/logo.jpg" width="220" alt="jsonisch — a database record between braces" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# jsonisch
|
|
2
6
|
|
|
3
7
|
> Schemas as values. A form library for apps where JSON-Schemas are **runtime
|
|
@@ -28,9 +32,10 @@ Most form libraries assume the shape of your form is known at build time —
|
|
|
28
32
|
a Zod schema in a module, types inferred from it, a hand-written component
|
|
29
33
|
per field. That assumption breaks the moment your app lets users customize
|
|
30
34
|
their forms: now the schema is a **value**, fetched from a database at
|
|
31
|
-
request time, different per tenant, edited without a deploy
|
|
32
|
-
compile-time type to infer against,
|
|
33
|
-
per field for a form that didn't
|
|
35
|
+
request time, different per tenant, edited without a deploy — or written
|
|
36
|
+
by an LLM a second ago. There is no compile-time type to infer against,
|
|
37
|
+
and nobody is hand-writing a component per field for a form that didn't
|
|
38
|
+
exist yesterday.
|
|
34
39
|
|
|
35
40
|
`jsonisch` starts from that world. It takes a JSON-Schema value, walks it
|
|
36
41
|
once, and gives you a fully reactive, validated form with the fields already
|
|
@@ -51,6 +56,13 @@ wired:
|
|
|
51
56
|
|
|
52
57
|
You bring the components; it brings everything else.
|
|
53
58
|
|
|
59
|
+
That last part matters more in the age of agents. The cheapest thing a
|
|
60
|
+
model can produce is a JSON value — and a JSON-Schema value is a complete
|
|
61
|
+
form definition. An agent that needs structured input from a human can
|
|
62
|
+
emit a schema and have a validated, fully wired form on screen in the
|
|
63
|
+
same request: no codegen, no deploy, and the schema it wrote is the same
|
|
64
|
+
contract that validates what the human sends back.
|
|
65
|
+
|
|
54
66
|
---
|
|
55
67
|
|
|
56
68
|
## Quickstart
|
|
@@ -156,22 +168,29 @@ formulas use to address the root record) and wires the dependency graph.
|
|
|
156
168
|
|
|
157
169
|
---
|
|
158
170
|
|
|
159
|
-
## Where jsonisch sits
|
|
171
|
+
## Where jsonisch sits
|
|
160
172
|
|
|
161
|
-
|
|
173
|
+
Two libraries are real lineage — we read their source and took ideas from
|
|
174
|
+
each deliberately:
|
|
162
175
|
|
|
163
|
-
- **
|
|
176
|
+
- **TanStack Form** — the **framework-agnostic core + thin adapters**
|
|
164
177
|
layout, and the **`createFormHook({ widgets })` composition/registry**
|
|
165
178
|
pattern: register your design-system widgets once, get a typed
|
|
166
179
|
`useAppForm` with them baked in.
|
|
167
|
-
- **
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
180
|
+
- **Formisch** — the **signal** reactivity model jsonisch's store is built
|
|
181
|
+
on (its own tiny signal implementation, no external lib): a keystroke
|
|
182
|
+
re-renders only the fields that depend on it.
|
|
183
|
+
|
|
184
|
+
One more deserves naming: **react-jsonschema-form** has been rendering
|
|
185
|
+
forms from JSON-Schema since long before us. jsonisch is not derived from
|
|
186
|
+
it — candidly, we didn't study it — the resemblance comes from sharing a
|
|
187
|
+
premise, not code. What's visibly different from here: jsonisch is
|
|
188
|
+
signal-reactive, ships no components of its own (your design system,
|
|
189
|
+
dispatched by control kind), injects validation instead of bundling it,
|
|
190
|
+
and evaluates schema-declared formulas as computed signals — **derived
|
|
191
|
+
values**, excluded from dirty-tracking and the submit payload *by
|
|
192
|
+
construction*. A careful comparison would make a good doc; we haven't
|
|
193
|
+
written it.
|
|
175
194
|
|
|
176
195
|
The re-render question — "when I type one character into a 60-field form,
|
|
177
196
|
what re-renders?" — has a two-decade history that signals largely closed,
|
|
@@ -679,6 +679,14 @@ interface JsonischPlugin<TState = unknown> {
|
|
|
679
679
|
* the subtree dirty walks that decide payload emission.
|
|
680
680
|
*/
|
|
681
681
|
fieldIsDirty?(ctx: PluginCtx<TState>, store: InternalValueStore): boolean;
|
|
682
|
+
/**
|
|
683
|
+
* 8b — whether THIS value field is a derived OUTPUT: the input
|
|
684
|
+
* projections (`getInput`, the validated submit output, the dirty
|
|
685
|
+
* whole-array emission) assemble around it, so its key is ABSENT from
|
|
686
|
+
* payloads instead of riding as own-key `undefined`. Only object
|
|
687
|
+
* ASSEMBLY consults this — a path-targeted leaf read stays raw.
|
|
688
|
+
*/
|
|
689
|
+
fieldIsOutput?(ctx: PluginCtx<TState>, store: InternalValueStore): boolean;
|
|
682
690
|
/**
|
|
683
691
|
* 9 — wraps a value field's own payload entry (the LOS-573 envelope):
|
|
684
692
|
* called for a dirty leaf with its outgoing value (`undefined` when only
|
|
@@ -718,7 +726,7 @@ type PluginsInput = ReadonlyArray<JsonischPlugin<unknown> | false | null | undef
|
|
|
718
726
|
* The hooks the driver precomputes implementer lists for (the per-field
|
|
719
727
|
* ones run in loops; scanning all plugins per field would be quadratic).
|
|
720
728
|
*/
|
|
721
|
-
declare const HOOK_NAMES: readonly ["buildScope", "reseedScope", "resetField", "syncInput", "syncInitial", "rebase", "transferField", "swapField", "fieldIsDirty", "encodeValue", "isDirty", "fieldSnapshot"];
|
|
729
|
+
declare const HOOK_NAMES: readonly ["buildScope", "reseedScope", "resetField", "syncInput", "syncInitial", "rebase", "transferField", "swapField", "fieldIsDirty", "fieldIsOutput", "encodeValue", "isDirty", "fieldSnapshot"];
|
|
722
730
|
type HookName = (typeof HOOK_NAMES)[number];
|
|
723
731
|
/**
|
|
724
732
|
* The resolved plugin runtime on a form store: the flat plugin list,
|
|
@@ -379,6 +379,7 @@ const KNOWN_MEMBERS = new Set([
|
|
|
379
379
|
"transferField",
|
|
380
380
|
"swapField",
|
|
381
381
|
"fieldIsDirty",
|
|
382
|
+
"fieldIsOutput",
|
|
382
383
|
"encodeValue",
|
|
383
384
|
"isDirty",
|
|
384
385
|
"fieldSnapshot"
|
|
@@ -397,6 +398,7 @@ const HOOK_NAMES = [
|
|
|
397
398
|
"transferField",
|
|
398
399
|
"swapField",
|
|
399
400
|
"fieldIsDirty",
|
|
401
|
+
"fieldIsOutput",
|
|
400
402
|
"encodeValue",
|
|
401
403
|
"isDirty",
|
|
402
404
|
"fieldSnapshot"
|
|
@@ -549,6 +551,17 @@ function fieldPluginDirty(form, store) {
|
|
|
549
551
|
return dirty;
|
|
550
552
|
}
|
|
551
553
|
/**
|
|
554
|
+
* Whether THIS value leaf is a derived OUTPUT (its key is absent from the
|
|
555
|
+
* input projections by construction). Reads every implementer for the same
|
|
556
|
+
* no-short-circuit reason as `fieldPluginDirty` — callers sit inside
|
|
557
|
+
* computeds and tracked snapshot reads.
|
|
558
|
+
*/
|
|
559
|
+
function fieldIsOutput(form, store) {
|
|
560
|
+
let output = false;
|
|
561
|
+
for (const plugin of form.pluginDriver?.hooks.fieldIsOutput ?? []) if (attributed(plugin, "fieldIsOutput", () => plugin.fieldIsOutput(ctxOf(form, plugin), store))) output = true;
|
|
562
|
+
return output;
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
552
565
|
* Whether any value leaf in the subtree has dirty plugin state — the
|
|
553
566
|
* plugin half of the dirty walks that decide payload emission (a mode flip
|
|
554
567
|
* with an unchanged value must still produce a payload). Reads array
|
|
@@ -992,15 +1005,24 @@ function focusFieldElement(internalFieldStore) {
|
|
|
992
1005
|
* `undefined` for nullish container inputs, or the leaf value for value
|
|
993
1006
|
* fields.
|
|
994
1007
|
*
|
|
1008
|
+
* With a form store, object assembly additionally skips derived OUTPUT
|
|
1009
|
+
* leaves (`fieldIsOutput`) — the key is ABSENT from the projection, never
|
|
1010
|
+
* own-key `undefined` (issue #29: `JSON.stringify` hides the leak, but
|
|
1011
|
+
* `Object.keys`/`in`/spread consumers see it). Leaf reads stay raw either
|
|
1012
|
+
* way: asking for the output field itself returns its stored input.
|
|
1013
|
+
*
|
|
995
1014
|
* @param internalFieldStore The field store to get input from.
|
|
1015
|
+
* @param internalFormStore The form store — pass it to project OUTPUT
|
|
1016
|
+
* leaves out of object assembly; omit for raw tree reads (plugin scope
|
|
1017
|
+
* resolution, per-field snapshots).
|
|
996
1018
|
*
|
|
997
1019
|
* @returns The field input.
|
|
998
1020
|
*/
|
|
999
|
-
function getFieldInput(internalFieldStore) {
|
|
1021
|
+
function getFieldInput(internalFieldStore, internalFormStore) {
|
|
1000
1022
|
if (internalFieldStore.kind === "array") {
|
|
1001
1023
|
if (internalFieldStore.input.value) {
|
|
1002
1024
|
const value = [];
|
|
1003
|
-
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index]);
|
|
1025
|
+
for (let index = 0; index < internalFieldStore.items.value.length; index++) value[index] = getFieldInput(internalFieldStore.children[index], internalFormStore);
|
|
1004
1026
|
return value;
|
|
1005
1027
|
}
|
|
1006
1028
|
return internalFieldStore.input.value;
|
|
@@ -1008,7 +1030,11 @@ function getFieldInput(internalFieldStore) {
|
|
|
1008
1030
|
if (internalFieldStore.kind === "object") {
|
|
1009
1031
|
if (internalFieldStore.input.value) {
|
|
1010
1032
|
const value = {};
|
|
1011
|
-
for (const key in internalFieldStore.children)
|
|
1033
|
+
for (const key in internalFieldStore.children) {
|
|
1034
|
+
const child = internalFieldStore.children[key];
|
|
1035
|
+
if (internalFormStore && child.kind === "value" && fieldIsOutput(internalFormStore, child)) continue;
|
|
1036
|
+
value[key] = getFieldInput(child, internalFormStore);
|
|
1037
|
+
}
|
|
1012
1038
|
return value;
|
|
1013
1039
|
}
|
|
1014
1040
|
return internalFieldStore.input.value;
|
|
@@ -1070,7 +1096,7 @@ function validateFormInput(internalFormStore, config) {
|
|
|
1070
1096
|
internalFormStore.validators++;
|
|
1071
1097
|
internalFormStore.isValidating.value = true;
|
|
1072
1098
|
try {
|
|
1073
|
-
const output = untrack(() => getFieldInput(internalFormStore));
|
|
1099
|
+
const output = untrack(() => getFieldInput(internalFormStore, internalFormStore));
|
|
1074
1100
|
const issues = internalFormStore.validator?.(output);
|
|
1075
1101
|
let fieldErrors;
|
|
1076
1102
|
if (issues && issues.length > 0) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as unwrapLeafInput, B as getFieldBool, L as untrack, M as batch, V as walkFieldStore, _ as resolveValueInput, b as dispatchReseedScope, c as isPresenceEqual, g as readOwn, j as createId, l as isSemanticEqual, m as containerPresence, n as validateFormInput, o as getFieldStoreChain, p as initializeFieldStore, t as internalOf, w as dispatchSyncInput } from "./form-ref-
|
|
1
|
+
import { A as unwrapLeafInput, B as getFieldBool, L as untrack, M as batch, V as walkFieldStore, _ as resolveValueInput, b as dispatchReseedScope, c as isPresenceEqual, g as readOwn, j as createId, l as isSemanticEqual, m as containerPresence, n as validateFormInput, o as getFieldStoreChain, p as initializeFieldStore, t as internalOf, w as dispatchSyncInput } from "./form-ref-WEtlz2iK.js";
|
|
2
2
|
|
|
3
3
|
//#region src/core/field/reset-item-state.ts
|
|
4
4
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { C as flattenSourceRow, D as derivation, F as AmountOrPercentEnvelope, G as CalcParseResult, H as EstimateMeta, K as DerivationMode, L as EntryMeta, M as ValidateFormInputConfig, N as ValidationResult, R as EntryMode, S as computeBag, V as EstimateEnvelope, W as CalcEngine, _ as bagger, b as ComputeBagOptions, c as CheckDefinition, d as ChecksConfig, f as Finding, h as SeverityConfig, i as formulaCheck, j as envelopes, l as CheckInstanceConfig, m as Severity, n as replaceCheckInstances, p as FormulaOptions, q as DerivedState, r as UNEVALUABLE_MESSAGE_ID, s as CheckContext, t as checks, u as CheckScope, w as visibility, x as collectionKeys, y as BaggerOptions, z as Envelope } from "./plugin-
|
|
2
|
-
import { A as VisibleWhen, C as FieldErrors, G as JsonSchema, K as Path, M as ControlKind, N as inferControl, _ as WireContract, a as InternalFormStore, g as PluginsInput, i as FormValidator, j as VisibleWhenOp, o as ValidationIssue, q as PathSegment, r as FormConfig, s as ValidationMode, t as FormRef, w as FieldKind, x as ContainerInput } from "./form-ref-
|
|
3
|
-
import { n as handleSubmit, t as SubmitHandler } from "./handle-submit-
|
|
1
|
+
import { C as flattenSourceRow, D as derivation, F as AmountOrPercentEnvelope, G as CalcParseResult, H as EstimateMeta, K as DerivationMode, L as EntryMeta, M as ValidateFormInputConfig, N as ValidationResult, R as EntryMode, S as computeBag, V as EstimateEnvelope, W as CalcEngine, _ as bagger, b as ComputeBagOptions, c as CheckDefinition, d as ChecksConfig, f as Finding, h as SeverityConfig, i as formulaCheck, j as envelopes, l as CheckInstanceConfig, m as Severity, n as replaceCheckInstances, p as FormulaOptions, q as DerivedState, r as UNEVALUABLE_MESSAGE_ID, s as CheckContext, t as checks, u as CheckScope, w as visibility, x as collectionKeys, y as BaggerOptions, z as Envelope } from "./plugin-CDzZKTHb.js";
|
|
2
|
+
import { A as VisibleWhen, C as FieldErrors, G as JsonSchema, K as Path, M as ControlKind, N as inferControl, _ as WireContract, a as InternalFormStore, g as PluginsInput, i as FormValidator, j as VisibleWhenOp, o as ValidationIssue, q as PathSegment, r as FormConfig, s as ValidationMode, t as FormRef, w as FieldKind, x as ContainerInput } from "./form-ref-FEumWYOE.js";
|
|
3
|
+
import { n as handleSubmit, t as SubmitHandler } from "./handle-submit-AUrq5T7Y.js";
|
|
4
4
|
|
|
5
5
|
//#region src/core/form/create-form-store.d.ts
|
|
6
6
|
/**
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as unwrapLeafInput, B as getFieldBool, C as dispatchSyncInitial, D as fieldPluginDirty, E as encodeFieldValue, L as untrack, M as batch, N as computed, O as hasPluginDirtyField, P as createSignal, S as dispatchSwapField, T as dispatchTransferField, V as walkFieldStore, _ as resolveValueInput, a as getFieldStore, c as isPresenceEqual, d as DEFAULT_ROOT_RECORD_ALIAS, f as createFormStore, g as readOwn, h as isSafeKey, i as focusFieldElement, j as createId, l as isSemanticEqual, m as containerPresence, n as validateFormInput, o as getFieldStoreChain, p as initializeFieldStore, r as getFieldInput, s as isEmptyish, t as internalOf, u as DEFAULT_EMPTY_INPUT, x as dispatchResetField, y as dispatchRebase, z as inferControl } from "./form-ref-
|
|
2
|
-
import { a as setFieldInput, i as computeContainerDirty, o as resetItemState, r as validateIfRequired, t as handleSubmit } from "./handle-submit-
|
|
3
|
-
import { A as bindAdopted, B as wrapEstimate, C as withRelationRowIdentity, E as envelopesKey, F as syncEstimateInput, H as getDirtyFieldInput, I as writeEnvelope, L as envelopesWire, M as decodeEstimateEnvelope, N as resolveEstimateMode, P as syncAmountOrPercentInput, R as isEnvelope, S as targetToKind, T as derivationKey, V as encodeScopeValues, _ as resolveRowFallback, b as relationParentFieldName, c as collectionKeys, d as visibility, i as formulaCheck, j as decodeAmountOrPercentEnvelope, k as adoptEnvelope, l as computeBag, m as resolveScopeValueAt, n as replaceCheckInstances, o as bagger, p as resolveScopeValue, r as UNEVALUABLE_MESSAGE_ID, t as checks, u as flattenSourceRow, w as mergeCollectionRows, x as relationRowIdentityProps, y as readRelationConfig, z as wrapAmountOrPercent } from "./plugin-
|
|
1
|
+
import { A as unwrapLeafInput, B as getFieldBool, C as dispatchSyncInitial, D as fieldPluginDirty, E as encodeFieldValue, L as untrack, M as batch, N as computed, O as hasPluginDirtyField, P as createSignal, S as dispatchSwapField, T as dispatchTransferField, V as walkFieldStore, _ as resolveValueInput, a as getFieldStore, c as isPresenceEqual, d as DEFAULT_ROOT_RECORD_ALIAS, f as createFormStore, g as readOwn, h as isSafeKey, i as focusFieldElement, j as createId, l as isSemanticEqual, m as containerPresence, n as validateFormInput, o as getFieldStoreChain, p as initializeFieldStore, r as getFieldInput, s as isEmptyish, t as internalOf, u as DEFAULT_EMPTY_INPUT, x as dispatchResetField, y as dispatchRebase, z as inferControl } from "./form-ref-WEtlz2iK.js";
|
|
2
|
+
import { a as setFieldInput, i as computeContainerDirty, o as resetItemState, r as validateIfRequired, t as handleSubmit } from "./handle-submit-De-yR66a.js";
|
|
3
|
+
import { A as bindAdopted, B as wrapEstimate, C as withRelationRowIdentity, E as envelopesKey, F as syncEstimateInput, H as getDirtyFieldInput, I as writeEnvelope, L as envelopesWire, M as decodeEstimateEnvelope, N as resolveEstimateMode, P as syncAmountOrPercentInput, R as isEnvelope, S as targetToKind, T as derivationKey, V as encodeScopeValues, _ as resolveRowFallback, b as relationParentFieldName, c as collectionKeys, d as visibility, i as formulaCheck, j as decodeAmountOrPercentEnvelope, k as adoptEnvelope, l as computeBag, m as resolveScopeValueAt, n as replaceCheckInstances, o as bagger, p as resolveScopeValue, r as UNEVALUABLE_MESSAGE_ID, t as checks, u as flattenSourceRow, w as mergeCollectionRows, x as relationRowIdentityProps, y as readRelationConfig, z as wrapAmountOrPercent } from "./plugin-Bdw1RuiF.js";
|
|
4
4
|
|
|
5
5
|
//#region src/core/codec/decode-record.ts
|
|
6
6
|
/**
|
|
@@ -743,7 +743,7 @@ function collectDirtyPaths(internalFieldStore, paths) {
|
|
|
743
743
|
*/
|
|
744
744
|
function getInput(form, path) {
|
|
745
745
|
const internal = internalOf(form);
|
|
746
|
-
return getFieldInput(path ? getFieldStore(internal, path) : internal);
|
|
746
|
+
return getFieldInput(path ? getFieldStore(internal, path) : internal, internal);
|
|
747
747
|
}
|
|
748
748
|
|
|
749
749
|
//#endregion
|
|
@@ -1388,6 +1388,9 @@ function derivation(engine) {
|
|
|
1388
1388
|
}
|
|
1389
1389
|
wireFormulaGraph(form, ctx.state, engine, scope.children, (dep, formValue) => resolveRowFallback(form, scope, dep, formValue));
|
|
1390
1390
|
},
|
|
1391
|
+
fieldIsOutput(ctx, store) {
|
|
1392
|
+
return store.control === "formula" && ctx.state.has(store);
|
|
1393
|
+
},
|
|
1391
1394
|
fieldSnapshot(ctx, store) {
|
|
1392
1395
|
const slot = ctx.state.get(store);
|
|
1393
1396
|
if (!slot) return {};
|
package/dist/plugin/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { A as EnvelopeState, B as EnvelopeSlot, E as DerivationState, I as AmountOrPercentSlot, O as DerivationSlot, P as validateFormInput, T as visibilityKey, U as EstimateSlot, a as ChecksState, g as BaggerState, k as derivationKey, o as checksKey, v as baggerKey } from "../plugin-
|
|
2
|
-
import { B as createSignal, D as InternalFieldStore, E as InternalBaseStore, F as ReadonlySignal, H as getListener, I as Signal, K as Path, L as Tracker, O as InternalObjectStore, P as Listener, R as batch, S as FieldElement, T as InternalArrayStore, U as untrack, V as createTracker, W as withListener, _ as WireContract, a as InternalFormStore, b as PluginKey, c as PluginDriver, d as hasPluginDirtyField, f as pluginsDirty, h as PluginCtx, k as InternalValueStore, l as encodeFieldValue, m as JsonischPlugin, n as internalOf, p as unwrapLeafInput, u as fieldPluginDirty, v as WireEnvelope, x as ContainerInput, y as FieldSlotKey, z as computed } from "../form-ref-
|
|
1
|
+
import { A as EnvelopeState, B as EnvelopeSlot, E as DerivationState, I as AmountOrPercentSlot, O as DerivationSlot, P as validateFormInput, T as visibilityKey, U as EstimateSlot, a as ChecksState, g as BaggerState, k as derivationKey, o as checksKey, v as baggerKey } from "../plugin-CDzZKTHb.js";
|
|
2
|
+
import { B as createSignal, D as InternalFieldStore, E as InternalBaseStore, F as ReadonlySignal, H as getListener, I as Signal, K as Path, L as Tracker, O as InternalObjectStore, P as Listener, R as batch, S as FieldElement, T as InternalArrayStore, U as untrack, V as createTracker, W as withListener, _ as WireContract, a as InternalFormStore, b as PluginKey, c as PluginDriver, d as hasPluginDirtyField, f as pluginsDirty, h as PluginCtx, k as InternalValueStore, l as encodeFieldValue, m as JsonischPlugin, n as internalOf, p as unwrapLeafInput, u as fieldPluginDirty, v as WireEnvelope, x as ContainerInput, y as FieldSlotKey, z as computed } from "../form-ref-FEumWYOE.js";
|
|
3
3
|
|
|
4
4
|
//#region src/core/field/focus-field-element.d.ts
|
|
5
5
|
|
|
@@ -40,11 +40,20 @@ declare function getFieldBool(internalFieldStore: InternalFieldStore, type: "err
|
|
|
40
40
|
* `undefined` for nullish container inputs, or the leaf value for value
|
|
41
41
|
* fields.
|
|
42
42
|
*
|
|
43
|
+
* With a form store, object assembly additionally skips derived OUTPUT
|
|
44
|
+
* leaves (`fieldIsOutput`) — the key is ABSENT from the projection, never
|
|
45
|
+
* own-key `undefined` (issue #29: `JSON.stringify` hides the leak, but
|
|
46
|
+
* `Object.keys`/`in`/spread consumers see it). Leaf reads stay raw either
|
|
47
|
+
* way: asking for the output field itself returns its stored input.
|
|
48
|
+
*
|
|
43
49
|
* @param internalFieldStore The field store to get input from.
|
|
50
|
+
* @param internalFormStore The form store — pass it to project OUTPUT
|
|
51
|
+
* leaves out of object assembly; omit for raw tree reads (plugin scope
|
|
52
|
+
* resolution, per-field snapshots).
|
|
44
53
|
*
|
|
45
54
|
* @returns The field input.
|
|
46
55
|
*/
|
|
47
|
-
declare function getFieldInput(internalFieldStore: InternalFieldStore): unknown;
|
|
56
|
+
declare function getFieldInput(internalFieldStore: InternalFieldStore, internalFormStore?: InternalFormStore): unknown;
|
|
48
57
|
//#endregion
|
|
49
58
|
//#region src/core/field/get-field-store.d.ts
|
|
50
59
|
/**
|
package/dist/plugin/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as unwrapLeafInput, B as getFieldBool, D as fieldPluginDirty, E as encodeFieldValue, F as createTracker, I as getListener, L as untrack, M as batch, N as computed, O as hasPluginDirtyField, P as createSignal, R as withListener, V as walkFieldStore, a as getFieldStore, i as focusFieldElement, k as pluginsDirty, n as validateFormInput, r as getFieldInput, t as internalOf } from "../form-ref-
|
|
2
|
-
import { D as FieldSlotKey, E as envelopesKey, H as getDirtyFieldInput, O as PluginKey, T as derivationKey, V as encodeScopeValues, _ as resolveRowFallback, a as checksKey, f as visibilityKey, g as findRowStore, h as canonicalRowOf, s as baggerKey, v as resolveRowScopeValue } from "../plugin-
|
|
1
|
+
import { A as unwrapLeafInput, B as getFieldBool, D as fieldPluginDirty, E as encodeFieldValue, F as createTracker, I as getListener, L as untrack, M as batch, N as computed, O as hasPluginDirtyField, P as createSignal, R as withListener, V as walkFieldStore, a as getFieldStore, i as focusFieldElement, k as pluginsDirty, n as validateFormInput, r as getFieldInput, t as internalOf } from "../form-ref-WEtlz2iK.js";
|
|
2
|
+
import { D as FieldSlotKey, E as envelopesKey, H as getDirtyFieldInput, O as PluginKey, T as derivationKey, V as encodeScopeValues, _ as resolveRowFallback, a as checksKey, f as visibilityKey, g as findRowStore, h as canonicalRowOf, s as baggerKey, v as resolveRowScopeValue } from "../plugin-Bdw1RuiF.js";
|
|
3
3
|
|
|
4
4
|
export { FieldSlotKey, PluginKey, baggerKey, batch, canonicalRowOf, checksKey, computed, createSignal, createTracker, derivationKey, encodeFieldValue, encodeScopeValues, envelopesKey, fieldPluginDirty, findRowStore, focusFieldElement, getDirtyFieldInput, getFieldBool, getFieldInput, getFieldStore, getListener, hasPluginDirtyField, internalOf, pluginsDirty, resolveRowFallback, resolveRowScopeValue, untrack, unwrapLeafInput, validateFormInput, visibilityKey, walkFieldStore, withListener };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { B as getFieldBool, D as fieldPluginDirty, E as encodeFieldValue, N as computed, O as hasPluginDirtyField, P as createSignal, _ as resolveValueInput, d as DEFAULT_ROOT_RECORD_ALIAS, g as readOwn, h as isSafeKey, l as isSemanticEqual, r as getFieldInput, s as isEmptyish, t as internalOf } from "./form-ref-
|
|
1
|
+
import { B as getFieldBool, D as fieldPluginDirty, E as encodeFieldValue, N as computed, O as hasPluginDirtyField, P as createSignal, _ as resolveValueInput, d as DEFAULT_ROOT_RECORD_ALIAS, g as readOwn, h as isSafeKey, l as isSemanticEqual, r as getFieldInput, s as isEmptyish, t as internalOf } from "./form-ref-WEtlz2iK.js";
|
|
2
2
|
|
|
3
3
|
//#region src/core/field/get-dirty-field-input.ts
|
|
4
4
|
/**
|
|
@@ -22,7 +22,7 @@ import { B as getFieldBool, D as fieldPluginDirty, E as encodeFieldValue, N as c
|
|
|
22
22
|
*/
|
|
23
23
|
function getDirtyFieldInput(internalFormStore, internalFieldStore) {
|
|
24
24
|
if (!getFieldBool(internalFieldStore, "isDirty") && !hasPluginDirtyField(internalFormStore, internalFieldStore)) return;
|
|
25
|
-
if (internalFieldStore.kind === "array") return encodeScopeValues(internalFormStore, internalFieldStore, getFieldInput(internalFieldStore));
|
|
25
|
+
if (internalFieldStore.kind === "array") return encodeScopeValues(internalFormStore, internalFieldStore, getFieldInput(internalFieldStore, internalFormStore));
|
|
26
26
|
if (internalFieldStore.kind === "object") {
|
|
27
27
|
if (internalFieldStore.input.value) {
|
|
28
28
|
const value = {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { D as InternalFieldStore, F as ReadonlySignal, G as JsonSchema, I as Signal, K as Path, a as InternalFormStore, b as PluginKey, m as JsonischPlugin, t as FormRef, y as FieldSlotKey } from "./form-ref-
|
|
1
|
+
import { D as InternalFieldStore, F as ReadonlySignal, G as JsonSchema, I as Signal, K as Path, a as InternalFormStore, b as PluginKey, m as JsonischPlugin, t as FormRef, y as FieldSlotKey } from "./form-ref-FEumWYOE.js";
|
|
2
2
|
|
|
3
3
|
//#region src/core/types/derivation.d.ts
|
|
4
4
|
|
|
@@ -263,7 +263,7 @@ type EnvelopeState = Map<InternalFieldStore, EnvelopeSlot>;
|
|
|
263
263
|
* side-channel to decode).
|
|
264
264
|
*/
|
|
265
265
|
declare function envelopes(): JsonischPlugin<EnvelopeState>;
|
|
266
|
-
declare module "
|
|
266
|
+
declare module "jsonisch/react" {
|
|
267
267
|
interface FieldStoreSlots {
|
|
268
268
|
/**
|
|
269
269
|
* The estimate/formula mode of an estimate field, `undefined`
|
|
@@ -357,7 +357,7 @@ type DerivationState = Map<InternalFieldStore, DerivationSlot>;
|
|
|
357
357
|
* plugin is a startup error instead.
|
|
358
358
|
*/
|
|
359
359
|
declare function derivation(engine: CalcEngine): JsonischPlugin<DerivationState>;
|
|
360
|
-
declare module "
|
|
360
|
+
declare module "jsonisch/react" {
|
|
361
361
|
interface FieldStoreSlots {
|
|
362
362
|
/**
|
|
363
363
|
* The mode-aware derived output of a formula/estimate field (what the
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as FieldErrors, G as JsonSchema, K as Path, M as ControlKind, S as FieldElement, a as InternalFormStore, i as FormValidator, r as FormConfig } from "../form-ref-
|
|
2
|
-
import { t as SubmitHandler } from "../handle-submit-
|
|
1
|
+
import { C as FieldErrors, G as JsonSchema, K as Path, M as ControlKind, S as FieldElement, a as InternalFormStore, i as FormValidator, r as FormConfig } from "../form-ref-FEumWYOE.js";
|
|
2
|
+
import { t as SubmitHandler } from "../handle-submit-AUrq5T7Y.js";
|
|
3
3
|
import { ComponentType, FormHTMLAttributes, ReactElement, ReactNode } from "react";
|
|
4
4
|
|
|
5
5
|
//#region src/react/types.d.ts
|
package/dist/react/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as getFieldBool, F as createTracker, a as getFieldStore, f as createFormStore, n as validateFormInput, r as getFieldInput, v as dispatchFieldSnapshot } from "../form-ref-
|
|
2
|
-
import { a as setFieldInput, n as setFieldBool, r as validateIfRequired, t as handleSubmit } from "../handle-submit-
|
|
1
|
+
import { B as getFieldBool, F as createTracker, a as getFieldStore, f as createFormStore, n as validateFormInput, r as getFieldInput, v as dispatchFieldSnapshot } from "../form-ref-WEtlz2iK.js";
|
|
2
|
+
import { a as setFieldInput, n as setFieldBool, r as validateIfRequired, t as handleSubmit } from "../handle-submit-De-yR66a.js";
|
|
3
3
|
import { useEffect, useLayoutEffect, useMemo, useSyncExternalStore } from "react";
|
|
4
4
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
5
|
|