@tai42/studio-sdk 9.2.0 → 9.2.1

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.
@@ -5,10 +5,19 @@
5
5
  * media-annotated schema renders the upload control instead; and when the form
6
6
  * supplies a completion provider, the input is backed by argument autocomplete.
7
7
  *
8
- * `JqField` is imported through the SDK's own `./jq` re-export — the ONE
8
+ * `JqField` is reached through the SDK's own `./jq` re-export — the ONE
9
9
  * `@tai42/jq-studio` instance the whole deployment shares — never from
10
10
  * `@tai42/jq-studio` directly, which would bundle a second copy and orphan its
11
11
  * worker (see the `jq` module doc-comment).
12
+ *
13
+ * That door is loaded LAZILY, through a dynamic `import('../jq')` behind
14
+ * {@link JqField}. The jq authoring door drags a heavy subgraph — the xyflow
15
+ * visual editor, a Web Worker entry, and a wasm engine chunk — that a form
16
+ * whose fields carry no `x-tai42-expression` annotation must never ship. A
17
+ * static import would pin that subgraph into every consumer that bundles the
18
+ * SDK (a host that externalises the SDK is unaffected either way); the dynamic
19
+ * import keeps it out of `schema-form`'s static graph and pulls it only when an
20
+ * annotated field actually mounts.
12
21
  */
13
22
  import type { ReactNode } from 'react';
14
23
  import type { ExpressionAnnotation, MediaUpload } from './classify';
@@ -1 +1 @@
1
- {"version":3,"file":"string-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AASvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAKpE,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,WAAW,EACX,KAAK,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,GAAG,SAAS,CA+DZ"}
1
+ {"version":3,"file":"string-field.d.ts","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AASvC,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAkBpE,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,WAAW,EACX,KAAK,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,OAAO,EACP,KAAK,EACL,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,UAAU,EAAE,oBAAoB,GAAG,SAAS,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC,GAAG,SAAS,CA+DZ"}
@@ -1,13 +1,24 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useCallback, useContext, useMemo, useState } from 'react';
2
+ import { Suspense, lazy, useCallback, useContext, useMemo, useState } from 'react';
3
3
  import { CompletionInput } from '../components/completion-input';
4
4
  import { Field } from '../components/field';
5
5
  import { AlertTriangleIcon } from '../components/icons';
6
- import { TextInput } from '../components/inputs';
6
+ import { TextInput, Textarea } from '../components/inputs';
7
7
  import { errorMessage } from '../errors';
8
- import { JqField } from '../jq';
9
8
  import { CompletionProviderContext } from './context';
10
9
  import { MediaField } from './media-field';
10
+ // The lazily-loaded jq door. Defining it at module scope (never inside a
11
+ // component) is what keeps the lazy component's identity stable across renders,
12
+ // so React resolves the chunk once and never re-suspends a mounted field. The
13
+ // `import('../jq')` here is a DYNAMIC import — the sole runtime edge from
14
+ // `schema-form` to the jq door — so the visual editor, worker, and wasm live in
15
+ // a split chunk that a non-annotated form never requests. The `type`-only
16
+ // import of `JqInputShapeDescriptor` above is erased at compile time and adds no
17
+ // such edge.
18
+ const JqField = lazy(async () => {
19
+ const { JqField } = await import('../jq');
20
+ return { default: JqField };
21
+ });
11
22
  export function StringField({ heading, description, error, format, media, expression, argName, value, required, onChange, }) {
12
23
  const completionProvider = useContext(CompletionProviderContext);
13
24
  const current = typeof value === 'string' ? value : '';
@@ -78,12 +89,28 @@ function CompletionField({ argName, value, onChange, provider, }) {
78
89
  * - `compact` — the form renders every sibling field with a visible label;
79
90
  * the compact variant (visually-hidden label, icon-only door) is for dense
80
91
  * host rows, which the schema form does not have.
92
+ *
93
+ * The door is code-split ({@link JqField} is a `lazy` component), so it mounts
94
+ * inside a `Suspense` boundary. Its fallback paints the resting shell —
95
+ * label/description/error chrome around the current value in a read-only
96
+ * multiline control — so the field holds its layout and keeps the value visible
97
+ * while the chunk resolves, and the swap to the live door does not flash.
81
98
  */
82
99
  function JqExpressionField({ heading, description, error, expression, argName, value, onChange, }) {
83
100
  // Memoised: the descriptor's identity feeds jq-studio's own memoisation, so a
84
101
  // fresh object each keystroke would defeat it.
85
102
  const shape = useMemo(() => expressionShape(expression, argName), [expression, argName]);
86
- return (_jsx(JqField, { label: heading, description: description, error: error, shape: shape, multiline: true, value: value, onChange: onChange }));
103
+ return (_jsx(Suspense, { fallback: _jsx(JqExpressionFieldSkeleton, { heading: heading, description: description, error: error, value: value }), children: _jsx(JqField, { label: heading, description: description, error: error, shape: shape, multiline: true, value: value, onChange: onChange }) }));
104
+ }
105
+ /**
106
+ * The resting shell shown while the jq door chunk loads. It mirrors the live
107
+ * door's footprint — the same label/description/error chrome wrapping a
108
+ * multiline control seeded with the current value — but the control is inert
109
+ * (read-only, `aria-busy`) because there is nothing to edit yet. Matching the
110
+ * footprint is what keeps the Suspense swap from shifting layout or flashing.
111
+ */
112
+ function JqExpressionFieldSkeleton({ heading, description, error, value, }) {
113
+ return (_jsx(Field, { label: heading, description: description, error: error, children: _jsx(Textarea, { value: value, readOnly: true, "aria-busy": "true" }) }));
87
114
  }
88
115
  /**
89
116
  * Map a classified expression annotation onto jq-studio's input-shape
@@ -1 +1 @@
1
- {"version":3,"file":"string-field.js","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"string-field.js","sourceRoot":"","sources":["../../src/schema-form/string-field.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tai42/studio-sdk",
3
- "version": "9.2.0",
3
+ "version": "9.2.1",
4
4
  "description": "The Studio plugin contract, shared UI components, and hooks that every feature builds on.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "tai42 <oss@tai42.ai>",
@@ -91,7 +91,7 @@
91
91
  "@radix-ui/react-tabs": "^1.1.16",
92
92
  "@radix-ui/react-tooltip": "^1.2.11",
93
93
  "@tai42/jq-studio": "^0.1.3",
94
- "@tai42/api-client": "9.2.0"
94
+ "@tai42/api-client": "9.2.1"
95
95
  },
96
96
  "scripts": {
97
97
  "build": "tsc -b tsconfig.build.json && node scripts/copy-assets.mjs",
@@ -5,25 +5,47 @@
5
5
  * media-annotated schema renders the upload control instead; and when the form
6
6
  * supplies a completion provider, the input is backed by argument autocomplete.
7
7
  *
8
- * `JqField` is imported through the SDK's own `./jq` re-export — the ONE
8
+ * `JqField` is reached through the SDK's own `./jq` re-export — the ONE
9
9
  * `@tai42/jq-studio` instance the whole deployment shares — never from
10
10
  * `@tai42/jq-studio` directly, which would bundle a second copy and orphan its
11
11
  * worker (see the `jq` module doc-comment).
12
+ *
13
+ * That door is loaded LAZILY, through a dynamic `import('../jq')` behind
14
+ * {@link JqField}. The jq authoring door drags a heavy subgraph — the xyflow
15
+ * visual editor, a Web Worker entry, and a wasm engine chunk — that a form
16
+ * whose fields carry no `x-tai42-expression` annotation must never ship. A
17
+ * static import would pin that subgraph into every consumer that bundles the
18
+ * SDK (a host that externalises the SDK is unaffected either way); the dynamic
19
+ * import keeps it out of `schema-form`'s static graph and pulls it only when an
20
+ * annotated field actually mounts.
12
21
  */
13
22
  import type { ReactNode } from 'react';
14
- import { useCallback, useContext, useMemo, useState } from 'react';
23
+ import { Suspense, lazy, useCallback, useContext, useMemo, useState } from 'react';
15
24
 
16
25
  import { CompletionInput } from '../components/completion-input';
17
26
  import { Field } from '../components/field';
18
27
  import { AlertTriangleIcon } from '../components/icons';
19
- import { TextInput } from '../components/inputs';
28
+ import { TextInput, Textarea } from '../components/inputs';
20
29
  import { errorMessage } from '../errors';
21
- import { JqField, type JqInputShapeDescriptor } from '../jq';
30
+ import type { JqInputShapeDescriptor } from '../jq';
22
31
  import type { ExpressionAnnotation, MediaUpload } from './classify';
23
32
  import { CompletionProviderContext } from './context';
24
33
  import { MediaField } from './media-field';
25
34
  import type { CompletionProvider } from './SchemaForm';
26
35
 
36
+ // The lazily-loaded jq door. Defining it at module scope (never inside a
37
+ // component) is what keeps the lazy component's identity stable across renders,
38
+ // so React resolves the chunk once and never re-suspends a mounted field. The
39
+ // `import('../jq')` here is a DYNAMIC import — the sole runtime edge from
40
+ // `schema-form` to the jq door — so the visual editor, worker, and wasm live in
41
+ // a split chunk that a non-annotated form never requests. The `type`-only
42
+ // import of `JqInputShapeDescriptor` above is erased at compile time and adds no
43
+ // such edge.
44
+ const JqField = lazy(async () => {
45
+ const { JqField } = await import('../jq');
46
+ return { default: JqField };
47
+ });
48
+
27
49
  export function StringField({
28
50
  heading,
29
51
  description,
@@ -191,6 +213,12 @@ function CompletionField({
191
213
  * - `compact` — the form renders every sibling field with a visible label;
192
214
  * the compact variant (visually-hidden label, icon-only door) is for dense
193
215
  * host rows, which the schema form does not have.
216
+ *
217
+ * The door is code-split ({@link JqField} is a `lazy` component), so it mounts
218
+ * inside a `Suspense` boundary. Its fallback paints the resting shell —
219
+ * label/description/error chrome around the current value in a read-only
220
+ * multiline control — so the field holds its layout and keeps the value visible
221
+ * while the chunk resolves, and the swap to the live door does not flash.
194
222
  */
195
223
  function JqExpressionField({
196
224
  heading,
@@ -213,15 +241,51 @@ function JqExpressionField({
213
241
  // fresh object each keystroke would defeat it.
214
242
  const shape = useMemo(() => expressionShape(expression, argName), [expression, argName]);
215
243
  return (
216
- <JqField
217
- label={heading}
218
- description={description}
219
- error={error}
220
- shape={shape}
221
- multiline
222
- value={value}
223
- onChange={onChange}
224
- />
244
+ <Suspense
245
+ fallback={
246
+ <JqExpressionFieldSkeleton
247
+ heading={heading}
248
+ description={description}
249
+ error={error}
250
+ value={value}
251
+ />
252
+ }
253
+ >
254
+ <JqField
255
+ label={heading}
256
+ description={description}
257
+ error={error}
258
+ shape={shape}
259
+ multiline
260
+ value={value}
261
+ onChange={onChange}
262
+ />
263
+ </Suspense>
264
+ );
265
+ }
266
+
267
+ /**
268
+ * The resting shell shown while the jq door chunk loads. It mirrors the live
269
+ * door's footprint — the same label/description/error chrome wrapping a
270
+ * multiline control seeded with the current value — but the control is inert
271
+ * (read-only, `aria-busy`) because there is nothing to edit yet. Matching the
272
+ * footprint is what keeps the Suspense swap from shifting layout or flashing.
273
+ */
274
+ function JqExpressionFieldSkeleton({
275
+ heading,
276
+ description,
277
+ error,
278
+ value,
279
+ }: {
280
+ heading: string;
281
+ description: string | undefined;
282
+ error: string | undefined;
283
+ value: string;
284
+ }): ReactNode {
285
+ return (
286
+ <Field label={heading} description={description} error={error}>
287
+ <Textarea value={value} readOnly aria-busy="true" />
288
+ </Field>
225
289
  );
226
290
  }
227
291