@tai42/studio-sdk 16.0.0 → 17.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/code-block.js +1 -1
- package/dist/components/code-block.js.map +1 -1
- package/dist/components/confirm-dialog.js +1 -1
- package/dist/components/confirm-dialog.js.map +1 -1
- package/dist/components/copy-field.js +1 -1
- package/dist/components/copy-field.js.map +1 -1
- package/dist/components/date-range-picker.d.ts.map +1 -1
- package/dist/components/date-range-picker.js.map +1 -1
- package/dist/components/dialog.d.ts.map +1 -1
- package/dist/components/dialog.js.map +1 -1
- package/dist/components/dirty-guard.d.ts.map +1 -1
- package/dist/components/dirty-guard.js +1 -1
- package/dist/components/dirty-guard.js.map +1 -1
- package/dist/components/explorer-body.d.ts +49 -0
- package/dist/components/explorer-body.d.ts.map +1 -0
- package/dist/components/explorer-body.js +67 -0
- package/dist/components/explorer-body.js.map +1 -0
- package/dist/components/explorer-page-size.d.ts +4 -0
- package/dist/components/explorer-page-size.d.ts.map +1 -0
- package/dist/components/explorer-page-size.js +36 -0
- package/dist/components/explorer-page-size.js.map +1 -0
- package/dist/components/explorer-tag-filter.d.ts +17 -0
- package/dist/components/explorer-tag-filter.d.ts.map +1 -0
- package/dist/components/explorer-tag-filter.js +29 -0
- package/dist/components/explorer-tag-filter.js.map +1 -0
- package/dist/components/explorer-tags.d.ts +22 -0
- package/dist/components/explorer-tags.d.ts.map +1 -0
- package/dist/components/explorer-tags.js +51 -0
- package/dist/components/explorer-tags.js.map +1 -0
- package/dist/components/explorer-view.d.ts +3 -17
- package/dist/components/explorer-view.d.ts.map +1 -1
- package/dist/components/explorer-view.js +53 -170
- package/dist/components/explorer-view.js.map +1 -1
- package/dist/components/extension-combo-builder.d.ts +1 -6
- package/dist/components/extension-combo-builder.d.ts.map +1 -1
- package/dist/components/extension-combo-builder.js +4 -79
- package/dist/components/extension-combo-builder.js.map +1 -1
- package/dist/components/extension-combo-parts.d.ts +44 -0
- package/dist/components/extension-combo-parts.d.ts.map +1 -0
- package/dist/components/extension-combo-parts.js +52 -0
- package/dist/components/extension-combo-parts.js.map +1 -0
- package/dist/components/field.d.ts +8 -0
- package/dist/components/field.d.ts.map +1 -1
- package/dist/components/field.js +0 -8
- package/dist/components/field.js.map +1 -1
- package/dist/components/fleet-report.d.ts +1 -1
- package/dist/components/fleet-report.d.ts.map +1 -1
- package/dist/components/fleet-report.js +51 -37
- package/dist/components/fleet-report.js.map +1 -1
- package/dist/components/folder-nav.d.ts.map +1 -1
- package/dist/components/folder-nav.js +1 -1
- package/dist/components/folder-nav.js.map +1 -1
- package/dist/components/form-dialog.d.ts.map +1 -1
- package/dist/components/form-dialog.js +1 -1
- package/dist/components/form-dialog.js.map +1 -1
- package/dist/components/icons/chrome-marks.d.ts +50 -0
- package/dist/components/icons/chrome-marks.d.ts.map +1 -0
- package/dist/components/icons/chrome-marks.js +51 -0
- package/dist/components/icons/chrome-marks.js.map +1 -0
- package/dist/components/icons/icon-frame.d.ts +29 -0
- package/dist/components/icons/icon-frame.d.ts.map +1 -0
- package/dist/components/icons/icon-frame.js +19 -0
- package/dist/components/icons/icon-frame.js.map +1 -0
- package/dist/components/icons/index.d.ts +40 -0
- package/dist/components/icons/index.d.ts.map +1 -0
- package/dist/components/icons/index.js +39 -0
- package/dist/components/icons/index.js.map +1 -0
- package/dist/components/icons/nav-map.d.ts +14 -0
- package/dist/components/icons/nav-map.d.ts.map +1 -0
- package/dist/components/icons/nav-map.js +28 -0
- package/dist/components/icons/nav-map.js.map +1 -0
- package/dist/components/icons/nav-marks.d.ts +44 -0
- package/dist/components/icons/nav-marks.d.ts.map +1 -0
- package/dist/components/icons/nav-marks.js +45 -0
- package/dist/components/icons/nav-marks.js.map +1 -0
- package/dist/components/icons/status-marks.d.ts +21 -0
- package/dist/components/icons/status-marks.d.ts.map +1 -0
- package/dist/components/icons/status-marks.js +22 -0
- package/dist/components/icons/status-marks.js.map +1 -0
- package/dist/components/icons/theme-marks.d.ts +9 -0
- package/dist/components/icons/theme-marks.d.ts.map +1 -0
- package/dist/components/icons/theme-marks.js +10 -0
- package/dist/components/icons/theme-marks.js.map +1 -0
- package/dist/components/inputs.js.map +1 -1
- package/dist/components/json-diff.d.ts.map +1 -1
- package/dist/components/json-diff.js +1 -3
- package/dist/components/json-diff.js.map +1 -1
- package/dist/components/json-tree-context.d.ts +13 -0
- package/dist/components/json-tree-context.d.ts.map +1 -0
- package/dist/components/json-tree-context.js +15 -0
- package/dist/components/json-tree-context.js.map +1 -0
- package/dist/components/json-tree-model.d.ts +56 -0
- package/dist/components/json-tree-model.d.ts.map +1 -0
- package/dist/components/json-tree-model.js +125 -0
- package/dist/components/json-tree-model.js.map +1 -0
- package/dist/components/json-tree-nodes.d.ts +35 -0
- package/dist/components/json-tree-nodes.d.ts.map +1 -0
- package/dist/components/json-tree-nodes.js +113 -0
- package/dist/components/json-tree-nodes.js.map +1 -0
- package/dist/components/json-tree.d.ts +20 -0
- package/dist/components/json-tree.d.ts.map +1 -1
- package/dist/components/json-tree.js +7 -315
- package/dist/components/json-tree.js.map +1 -1
- package/dist/components/json-value-format.d.ts +20 -0
- package/dist/components/json-value-format.d.ts.map +1 -0
- package/dist/components/json-value-format.js +63 -0
- package/dist/components/json-value-format.js.map +1 -0
- package/dist/components/markdown-blocks.d.ts +38 -0
- package/dist/components/markdown-blocks.d.ts.map +1 -0
- package/dist/components/markdown-blocks.js +168 -0
- package/dist/components/markdown-blocks.js.map +1 -0
- package/dist/components/markdown-inline.d.ts +24 -0
- package/dist/components/markdown-inline.d.ts.map +1 -0
- package/dist/components/markdown-inline.js +257 -0
- package/dist/components/markdown-inline.js.map +1 -0
- package/dist/components/markdown.d.ts +3 -52
- package/dist/components/markdown.d.ts.map +1 -1
- package/dist/components/markdown.js +4 -376
- package/dist/components/markdown.js.map +1 -1
- package/dist/components/observer-registry.d.ts +38 -0
- package/dist/components/observer-registry.d.ts.map +1 -0
- package/dist/components/observer-registry.js +131 -0
- package/dist/components/observer-registry.js.map +1 -0
- package/dist/components/overflow-measure.d.ts +38 -0
- package/dist/components/overflow-measure.d.ts.map +1 -0
- package/dist/components/overflow-measure.js +54 -0
- package/dist/components/overflow-measure.js.map +1 -0
- package/dist/components/page-fill.d.ts.map +1 -1
- package/dist/components/page-fill.js.map +1 -1
- package/dist/components/prose-regions.d.ts +81 -0
- package/dist/components/prose-regions.d.ts.map +1 -0
- package/dist/components/prose-regions.js +128 -0
- package/dist/components/prose-regions.js.map +1 -0
- package/dist/components/radio-group.d.ts.map +1 -1
- package/dist/components/radio-group.js.map +1 -1
- package/dist/components/scroll-region.d.ts +24 -0
- package/dist/components/scroll-region.d.ts.map +1 -1
- package/dist/components/scroll-region.js +3 -322
- package/dist/components/scroll-region.js.map +1 -1
- package/dist/components/tab-stop-parse.d.ts +53 -0
- package/dist/components/tab-stop-parse.d.ts.map +1 -0
- package/dist/components/tab-stop-parse.js +202 -0
- package/dist/components/tab-stop-parse.js.map +1 -0
- package/dist/components/table.d.ts +1 -1
- package/dist/components/table.d.ts.map +1 -1
- package/dist/components/tags.d.ts.map +1 -1
- package/dist/components/tags.js +1 -1
- package/dist/components/tags.js.map +1 -1
- package/dist/components/templated-text-field.d.ts +1 -1
- package/dist/components/templated-text-field.d.ts.map +1 -1
- package/dist/components/templated-text-field.js +10 -174
- package/dist/components/templated-text-field.js.map +1 -1
- package/dist/components/templated-text-kwargs-editor.d.ts +24 -0
- package/dist/components/templated-text-kwargs-editor.d.ts.map +1 -0
- package/dist/components/templated-text-kwargs-editor.js +48 -0
- package/dist/components/templated-text-kwargs-editor.js.map +1 -0
- package/dist/components/templated-text-kwargs.d.ts +37 -0
- package/dist/components/templated-text-kwargs.d.ts.map +1 -0
- package/dist/components/templated-text-kwargs.js +66 -0
- package/dist/components/templated-text-kwargs.js.map +1 -0
- package/dist/components/templated-text-source.d.ts +33 -0
- package/dist/components/templated-text-source.d.ts.map +1 -0
- package/dist/components/templated-text-source.js +53 -0
- package/dist/components/templated-text-source.js.map +1 -0
- package/dist/components/tool-picker-parts.d.ts +39 -0
- package/dist/components/tool-picker-parts.d.ts.map +1 -0
- package/dist/components/tool-picker-parts.js +87 -0
- package/dist/components/tool-picker-parts.js.map +1 -0
- package/dist/components/tool-picker.d.ts +1 -2
- package/dist/components/tool-picker.d.ts.map +1 -1
- package/dist/components/tool-picker.js +4 -66
- package/dist/components/tool-picker.js.map +1 -1
- package/dist/components/version-history-panel.d.ts.map +1 -1
- package/dist/components/version-history-panel.js +7 -34
- package/dist/components/version-history-panel.js.map +1 -1
- package/dist/components/version-history-rows.d.ts +48 -0
- package/dist/components/version-history-rows.d.ts.map +1 -0
- package/dist/components/version-history-rows.js +51 -0
- package/dist/components/version-history-rows.js.map +1 -0
- package/dist/components/view-toggle.d.ts.map +1 -1
- package/dist/components/view-toggle.js.map +1 -1
- package/dist/element-slot.d.ts +11 -0
- package/dist/element-slot.d.ts.map +1 -1
- package/dist/element-slot.js +0 -11
- package/dist/element-slot.js.map +1 -1
- package/dist/guards.d.ts +6 -0
- package/dist/guards.d.ts.map +1 -0
- package/dist/guards.js +8 -0
- package/dist/guards.js.map +1 -0
- package/dist/hooks/interactions-connection.d.ts +43 -0
- package/dist/hooks/interactions-connection.d.ts.map +1 -0
- package/dist/hooks/interactions-connection.js +171 -0
- package/dist/hooks/interactions-connection.js.map +1 -0
- package/dist/hooks/interactions-stream.d.ts +80 -0
- package/dist/hooks/interactions-stream.d.ts.map +1 -0
- package/dist/hooks/interactions-stream.js +233 -0
- package/dist/hooks/interactions-stream.js.map +1 -0
- package/dist/hooks/useApi.d.ts +2259 -2189
- package/dist/hooks/useApi.d.ts.map +1 -1
- package/dist/hooks/useApi.js +0 -11
- package/dist/hooks/useApi.js.map +1 -1
- package/dist/hooks/useAuth.d.ts +6 -0
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +0 -6
- package/dist/hooks/useAuth.js.map +1 -1
- package/dist/hooks/useCapabilities.d.ts +18 -2
- package/dist/hooks/useCapabilities.d.ts.map +1 -1
- package/dist/hooks/useCapabilities.js +1 -17
- package/dist/hooks/useCapabilities.js.map +1 -1
- package/dist/hooks/useSse.d.ts +34 -6
- package/dist/hooks/useSse.d.ts.map +1 -1
- package/dist/hooks/useSse.js +27 -471
- package/dist/hooks/useSse.js.map +1 -1
- package/dist/hooks/useSystemKinds.d.ts +1 -1
- package/dist/hooks/useSystemKinds.d.ts.map +1 -1
- package/dist/hooks/useSystemKinds.js +0 -18
- package/dist/hooks/useSystemKinds.js.map +1 -1
- package/dist/hooks/useTheme.d.ts +15 -0
- package/dist/hooks/useTheme.d.ts.map +1 -1
- package/dist/hooks/useTheme.js +0 -15
- package/dist/hooks/useTheme.js.map +1 -1
- package/dist/hooks/useToolDisplayNames.d.ts +0 -14
- package/dist/hooks/useToolDisplayNames.d.ts.map +1 -1
- package/dist/hooks/useToolDisplayNames.js +0 -14
- package/dist/hooks/useToolDisplayNames.js.map +1 -1
- package/dist/host.d.ts +3 -3
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +2 -9
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +103 -103
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -62
- package/dist/index.js.map +1 -1
- package/dist/navigation/app-link.d.ts +25 -0
- package/dist/navigation/app-link.d.ts.map +1 -0
- package/dist/navigation/app-link.js +33 -0
- package/dist/navigation/app-link.js.map +1 -0
- package/dist/navigation/context.d.ts +3 -20
- package/dist/navigation/context.d.ts.map +1 -1
- package/dist/navigation/context.js +7 -267
- package/dist/navigation/context.js.map +1 -1
- package/dist/navigation/entry-state.d.ts +23 -0
- package/dist/navigation/entry-state.d.ts.map +1 -0
- package/dist/navigation/entry-state.js +39 -0
- package/dist/navigation/entry-state.js.map +1 -0
- package/dist/navigation/guard-registry.d.ts +30 -0
- package/dist/navigation/guard-registry.d.ts.map +1 -0
- package/dist/navigation/guard-registry.js +46 -0
- package/dist/navigation/guard-registry.js.map +1 -0
- package/dist/navigation/guarded-navigation.d.ts +24 -0
- package/dist/navigation/guarded-navigation.d.ts.map +1 -0
- package/dist/navigation/guarded-navigation.js +102 -0
- package/dist/navigation/guarded-navigation.js.map +1 -0
- package/dist/navigation/index.d.ts +5 -4
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +2 -1
- package/dist/navigation/index.js.map +1 -1
- package/dist/navigation/types.d.ts +8 -11
- package/dist/navigation/types.d.ts.map +1 -1
- package/dist/navigation/use-back-forward-guard.d.ts +12 -0
- package/dist/navigation/use-back-forward-guard.d.ts.map +1 -0
- package/dist/navigation/use-back-forward-guard.js +75 -0
- package/dist/navigation/use-back-forward-guard.js.map +1 -0
- package/dist/navigation/use-search-commit.d.ts.map +1 -1
- package/dist/navigation/use-search-commit.js.map +1 -1
- package/dist/plugin/host-state.d.ts.map +1 -1
- package/dist/plugin/host-state.js.map +1 -1
- package/dist/plugin/registry.d.ts +6 -15
- package/dist/plugin/registry.d.ts.map +1 -1
- package/dist/plugin/registry.js +83 -75
- package/dist/plugin/registry.js.map +1 -1
- package/dist/schema-editor/SchemaEditor.d.ts.map +1 -1
- package/dist/schema-editor/SchemaEditor.js.map +1 -1
- package/dist/schema-editor/index.d.ts +3 -3
- package/dist/schema-editor/index.d.ts.map +1 -1
- package/dist/schema-editor/index.js +1 -6
- package/dist/schema-editor/index.js.map +1 -1
- package/dist/schema-form/SecretRefField.d.ts +18 -3
- package/dist/schema-form/SecretRefField.d.ts.map +1 -1
- package/dist/schema-form/SecretRefField.js +21 -26
- package/dist/schema-form/SecretRefField.js.map +1 -1
- package/dist/schema-form/classify.d.ts +1 -113
- package/dist/schema-form/classify.d.ts.map +1 -1
- package/dist/schema-form/classify.js +174 -246
- package/dist/schema-form/classify.js.map +1 -1
- package/dist/schema-form/context.d.ts +6 -0
- package/dist/schema-form/context.d.ts.map +1 -1
- package/dist/schema-form/context.js +0 -6
- package/dist/schema-form/context.js.map +1 -1
- package/dist/schema-form/default-value.d.ts.map +1 -1
- package/dist/schema-form/default-value.js +42 -19
- package/dist/schema-form/default-value.js.map +1 -1
- package/dist/schema-form/enum-field.d.ts +1 -1
- package/dist/schema-form/enum-field.d.ts.map +1 -1
- package/dist/schema-form/field-group.d.ts +6 -0
- package/dist/schema-form/field-group.d.ts.map +1 -1
- package/dist/schema-form/field-group.js +0 -6
- package/dist/schema-form/field-group.js.map +1 -1
- package/dist/schema-form/field-model.d.ts +121 -0
- package/dist/schema-form/field-model.d.ts.map +1 -0
- package/dist/schema-form/field-model.js +2 -0
- package/dist/schema-form/field-model.js.map +1 -0
- package/dist/schema-form/field-node.d.ts.map +1 -1
- package/dist/schema-form/field-node.js +25 -14
- package/dist/schema-form/field-node.js.map +1 -1
- package/dist/schema-form/index.d.ts +8 -8
- package/dist/schema-form/index.d.ts.map +1 -1
- package/dist/schema-form/index.js +3 -34
- package/dist/schema-form/index.js.map +1 -1
- package/dist/schema-form/json-field.d.ts +19 -0
- package/dist/schema-form/json-field.d.ts.map +1 -1
- package/dist/schema-form/json-field.js +0 -19
- package/dist/schema-form/json-field.js.map +1 -1
- package/dist/schema-form/media-field.d.ts +1 -1
- package/dist/schema-form/media-field.d.ts.map +1 -1
- package/dist/schema-form/media-field.js +49 -30
- package/dist/schema-form/media-field.js.map +1 -1
- package/dist/schema-form/record-field.d.ts +12 -0
- package/dist/schema-form/record-field.d.ts.map +1 -1
- package/dist/schema-form/record-field.js +1 -13
- package/dist/schema-form/record-field.js.map +1 -1
- package/dist/schema-form/string-annotations.d.ts +20 -0
- package/dist/schema-form/string-annotations.d.ts.map +1 -0
- package/dist/schema-form/string-annotations.js +105 -0
- package/dist/schema-form/string-annotations.js.map +1 -0
- package/dist/schema-form/string-field.d.ts +1 -1
- package/dist/schema-form/string-field.d.ts.map +1 -1
- package/dist/schema-form/string-field.js +1 -1
- package/dist/schema-form/string-field.js.map +1 -1
- package/dist/schema-form/union-field.d.ts +1 -1
- package/dist/schema-form/union-field.d.ts.map +1 -1
- package/dist/schema-form/union-field.js.map +1 -1
- package/dist/schema-form/union.d.ts +8 -1
- package/dist/schema-form/union.d.ts.map +1 -1
- package/dist/schema-form/union.js +0 -7
- package/dist/schema-form/union.js.map +1 -1
- package/dist/schema-form/validate.d.ts.map +1 -1
- package/dist/schema-form/validate.js +126 -105
- package/dist/schema-form/validate.js.map +1 -1
- package/dist/state-binding/AdapterMapping.d.ts.map +1 -1
- package/dist/state-binding/AdapterMapping.js +0 -0
- package/dist/state-binding/AdapterMapping.js.map +1 -1
- package/dist/state-binding/BindingJqField.d.ts.map +1 -1
- package/dist/state-binding/BindingJqField.js +2 -2
- package/dist/state-binding/BindingJqField.js.map +1 -1
- package/dist/state-binding/InputInjectionRow.d.ts.map +1 -1
- package/dist/state-binding/InputInjectionRow.js +3 -3
- package/dist/state-binding/InputInjectionRow.js.map +1 -1
- package/dist/state-binding/StateAttachRow.d.ts.map +1 -1
- package/dist/state-binding/StateAttachRow.js +57 -41
- package/dist/state-binding/StateAttachRow.js.map +1 -1
- package/dist/state-binding/StateBindingSection.d.ts.map +1 -1
- package/dist/state-binding/StateBindingSection.js.map +1 -1
- package/dist/state-binding/SubjectScopeFields.d.ts.map +1 -1
- package/dist/state-binding/SubjectScopeFields.js.map +1 -1
- package/dist/state-binding/UpdateRow.d.ts.map +1 -1
- package/dist/state-binding/UpdateRow.js +2 -2
- package/dist/state-binding/UpdateRow.js.map +1 -1
- package/dist/state-binding/adapter-mapping-row.d.ts +17 -0
- package/dist/state-binding/adapter-mapping-row.d.ts.map +1 -0
- package/dist/state-binding/adapter-mapping-row.js +87 -0
- package/dist/state-binding/adapter-mapping-row.js.map +1 -0
- package/dist/state-binding/index.d.ts +21 -21
- package/dist/state-binding/index.d.ts.map +1 -1
- package/dist/state-binding/index.js +9 -15
- package/dist/state-binding/index.js.map +1 -1
- package/dist/state-binding/templated-text-catalog.d.ts.map +1 -1
- package/dist/state-binding/templated-text-catalog.js.map +1 -1
- package/dist/state-binding/types.d.ts +2 -2
- package/dist/state-binding/types.d.ts.map +1 -1
- package/dist/structured-output/StructuredOutput.d.ts.map +1 -1
- package/dist/structured-output/StructuredOutput.js +1 -3
- package/dist/structured-output/StructuredOutput.js.map +1 -1
- package/package.json +2 -2
- package/src/components/code-block.tsx +1 -1
- package/src/components/confirm-dialog.tsx +1 -1
- package/src/components/copy-field.tsx +1 -1
- package/src/components/date-range-picker.tsx +1 -1
- package/src/components/dialog.tsx +1 -1
- package/src/components/dirty-guard.tsx +3 -3
- package/src/components/explorer-body.tsx +239 -0
- package/src/components/explorer-page-size.ts +39 -0
- package/src/components/explorer-tag-filter.tsx +80 -0
- package/src/components/explorer-tags.ts +64 -0
- package/src/components/explorer-view.tsx +115 -367
- package/src/components/extension-combo-builder.tsx +35 -153
- package/src/components/extension-combo-parts.tsx +236 -0
- package/src/components/field.tsx +1 -1
- package/src/components/fleet-report.tsx +98 -55
- package/src/components/folder-nav.tsx +2 -2
- package/src/components/form-dialog.tsx +2 -2
- package/src/components/icons/chrome-marks.tsx +195 -0
- package/src/components/icons/icon-frame.tsx +50 -0
- package/src/components/icons/index.ts +84 -0
- package/src/components/icons/nav-map.ts +55 -0
- package/src/components/icons/nav-marks.tsx +205 -0
- package/src/components/icons/status-marks.tsx +46 -0
- package/src/components/icons/theme-marks.tsx +33 -0
- package/src/components/inputs.tsx +1 -1
- package/src/components/json-diff.tsx +1 -4
- package/src/components/json-tree-context.ts +26 -0
- package/src/components/json-tree-model.ts +139 -0
- package/src/components/json-tree-nodes.tsx +224 -0
- package/src/components/json-tree.tsx +15 -434
- package/src/components/json-value-format.ts +64 -0
- package/src/components/markdown-blocks.ts +198 -0
- package/src/components/markdown-inline.tsx +365 -0
- package/src/components/markdown.tsx +6 -472
- package/src/components/observer-registry.ts +139 -0
- package/src/components/overflow-measure.ts +69 -0
- package/src/components/page-fill.tsx +1 -1
- package/src/components/prose-regions.ts +153 -0
- package/src/components/radio-group.tsx +1 -1
- package/src/components/scroll-region.tsx +22 -361
- package/src/components/tab-stop-parse.ts +217 -0
- package/src/components/table.tsx +1 -1
- package/src/components/tags.tsx +2 -2
- package/src/components/templated-text-field.tsx +39 -332
- package/src/components/templated-text-kwargs-editor.tsx +147 -0
- package/src/components/templated-text-kwargs.ts +92 -0
- package/src/components/templated-text-source.tsx +226 -0
- package/src/components/tool-picker-parts.tsx +184 -0
- package/src/components/tool-picker.tsx +22 -114
- package/src/components/version-history-panel.tsx +39 -143
- package/src/components/version-history-rows.tsx +220 -0
- package/src/components/view-toggle.tsx +1 -1
- package/src/element-slot.ts +1 -1
- package/src/guards.ts +7 -0
- package/src/hooks/interactions-connection.ts +227 -0
- package/src/hooks/interactions-stream.ts +274 -0
- package/src/hooks/useApi.ts +1 -1
- package/src/hooks/useAuth.ts +1 -1
- package/src/hooks/useCapabilities.ts +3 -3
- package/src/hooks/useSse.ts +51 -478
- package/src/hooks/useSystemKinds.tsx +2 -2
- package/src/hooks/useTheme.ts +1 -1
- package/src/hooks/useToolDisplayNames.tsx +2 -2
- package/src/host.ts +7 -7
- package/src/index.ts +292 -292
- package/src/navigation/app-link.tsx +70 -0
- package/src/navigation/context.tsx +12 -331
- package/src/navigation/entry-state.ts +42 -0
- package/src/navigation/guard-registry.ts +65 -0
- package/src/navigation/guarded-navigation.ts +147 -0
- package/src/navigation/index.ts +14 -14
- package/src/navigation/types.ts +8 -11
- package/src/navigation/use-back-forward-guard.ts +90 -0
- package/src/navigation/use-search-commit.ts +1 -1
- package/src/plugin/host-state.ts +1 -1
- package/src/plugin/registry.ts +111 -90
- package/src/schema-editor/SchemaEditor.tsx +1 -1
- package/src/schema-editor/index.ts +3 -3
- package/src/schema-form/SecretRefField.tsx +122 -72
- package/src/schema-form/classify.ts +245 -396
- package/src/schema-form/context.ts +1 -1
- package/src/schema-form/default-value.ts +48 -17
- package/src/schema-form/enum-field.tsx +1 -1
- package/src/schema-form/field-group.tsx +1 -1
- package/src/schema-form/field-model.ts +133 -0
- package/src/schema-form/field-node.tsx +95 -39
- package/src/schema-form/index.ts +10 -10
- package/src/schema-form/json-field.tsx +1 -1
- package/src/schema-form/media-field.tsx +136 -67
- package/src/schema-form/record-field.tsx +2 -2
- package/src/schema-form/string-annotations.ts +111 -0
- package/src/schema-form/string-field.tsx +2 -2
- package/src/schema-form/union-field.tsx +3 -2
- package/src/schema-form/union.ts +1 -1
- package/src/schema-form/validate.ts +185 -104
- package/src/state-binding/AdapterMapping.tsx +0 -0
- package/src/state-binding/BindingJqField.tsx +3 -3
- package/src/state-binding/InputInjectionRow.tsx +4 -4
- package/src/state-binding/StateAttachRow.tsx +229 -154
- package/src/state-binding/StateBindingSection.tsx +1 -1
- package/src/state-binding/SubjectScopeFields.tsx +1 -1
- package/src/state-binding/UpdateRow.tsx +3 -3
- package/src/state-binding/adapter-mapping-row.tsx +232 -0
- package/src/state-binding/index.ts +43 -43
- package/src/state-binding/templated-text-catalog.ts +0 -1
- package/src/state-binding/types.ts +2 -2
- package/src/structured-output/StructuredOutput.tsx +1 -4
- package/dist/components/icons.d.ts +0 -160
- package/dist/components/icons.d.ts.map +0 -1
- package/dist/components/icons.js +0 -160
- package/dist/components/icons.js.map +0 -1
- package/src/components/icons.tsx +0 -586
|
@@ -18,20 +18,23 @@
|
|
|
18
18
|
* The scrolling pane IS the scrolling box, carrying the region attributes itself
|
|
19
19
|
* rather than nesting a `ScrollRegion` that would add a second scroller.
|
|
20
20
|
*/
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
useCallback,
|
|
24
|
-
useContext,
|
|
25
|
-
useEffect,
|
|
26
|
-
useMemo,
|
|
27
|
-
useRef,
|
|
28
|
-
useState,
|
|
29
|
-
} from 'react';
|
|
30
|
-
import type { CSSProperties, MouseEvent as ReactMouseEvent, ReactElement } from 'react';
|
|
21
|
+
import type { ReactElement } from 'react';
|
|
22
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
31
23
|
|
|
32
|
-
import {
|
|
24
|
+
import { useClipboardCopy } from '../hooks/useClipboardCopy';
|
|
25
|
+
import { XCircleIcon } from './icons';
|
|
26
|
+
import { JsonTreeContext, type JsonTreeContextValue } from './json-tree-context';
|
|
27
|
+
import {
|
|
28
|
+
type Baseline,
|
|
29
|
+
computeOpen,
|
|
30
|
+
expandedOpenPaths,
|
|
31
|
+
initialBaseline,
|
|
32
|
+
isContainer,
|
|
33
|
+
PAGE_SIZE,
|
|
34
|
+
} from './json-tree-model';
|
|
35
|
+
import { COPY_LABEL, CopyButton, JsonNode } from './json-tree-nodes';
|
|
36
|
+
import { copyFailed, NO_CLIPBOARD, serializeForCopy } from './json-value-format';
|
|
33
37
|
import { useOverflowRegion } from './scroll-region';
|
|
34
|
-
import { COPIED_LABEL, COPIED_RESET_MS, useClipboardCopy } from '../hooks/useClipboardCopy';
|
|
35
38
|
|
|
36
39
|
export interface JsonTreeProps {
|
|
37
40
|
readonly data: unknown;
|
|
@@ -48,428 +51,6 @@ export interface JsonTreeProps {
|
|
|
48
51
|
/** The region's name when the caller supplies none. */
|
|
49
52
|
const DEFAULT_LABEL = 'JSON';
|
|
50
53
|
|
|
51
|
-
/** The deepest level opened by the guarded default; deeper nodes start collapsed. */
|
|
52
|
-
const AUTO_EXPAND_DEPTH = 1;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* The deepest level EXPAND-ALL reaches. Past it a node opens only on an explicit
|
|
56
|
-
* click, so the one action that opens the whole tree still cannot force an
|
|
57
|
-
* unbounded-depth payload into the DOM in a single stroke.
|
|
58
|
-
*/
|
|
59
|
-
const MAX_AUTO_DEPTH = 6;
|
|
60
|
-
|
|
61
|
-
/** Children rendered per page; the rest wait behind a "show more" control. */
|
|
62
|
-
const PAGE_SIZE = 100;
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* The most rendered nodes EXPAND-ALL may auto-open in one stroke. The depth cap and
|
|
66
|
-
* the per-page limit each bound ONE dimension, but a payload that is wide AND deep
|
|
67
|
-
* multiplies them — auto-opening every node up to the cap would lay out on the order
|
|
68
|
-
* of PAGE_SIZE^depth nodes and freeze the tab. Expand-all instead opens containers
|
|
69
|
-
* breadth-first only until this budget is spent; a node past it stays collapsed and
|
|
70
|
-
* opens on an explicit click, so a huge payload opens a bounded, usable subset.
|
|
71
|
-
*/
|
|
72
|
-
const AUTO_EXPAND_NODE_BUDGET = 1500;
|
|
73
|
-
|
|
74
|
-
/** A copy control's resting face; whichever is exposed is also its accessible name. */
|
|
75
|
-
const COPY_LABEL = 'Copy';
|
|
76
|
-
|
|
77
|
-
/** Shown when the browser offers no clipboard at all (any non-secure context). */
|
|
78
|
-
const NO_CLIPBOARD =
|
|
79
|
-
'This browser will not write to the clipboard here. Select the value and copy it by hand.';
|
|
80
|
-
|
|
81
|
-
/** Shown when the write, or the value's serialization, is offered and refused. */
|
|
82
|
-
function copyFailed(reason: unknown): string {
|
|
83
|
-
const detail = reason instanceof Error ? reason.message : String(reason);
|
|
84
|
-
return `Copy failed: ${detail}.`;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
88
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Whether a value is a disclosure (object or array) rather than a leaf. */
|
|
92
|
-
function isContainer(value: unknown): boolean {
|
|
93
|
-
return Array.isArray(value) || isRecord(value);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function primitiveText(value: unknown): string {
|
|
97
|
-
if (value === null) return 'null';
|
|
98
|
-
switch (typeof value) {
|
|
99
|
-
case 'undefined':
|
|
100
|
-
return 'undefined';
|
|
101
|
-
case 'string':
|
|
102
|
-
return `"${value}"`;
|
|
103
|
-
case 'number':
|
|
104
|
-
case 'bigint':
|
|
105
|
-
case 'boolean':
|
|
106
|
-
return String(value);
|
|
107
|
-
case 'symbol':
|
|
108
|
-
return value.toString();
|
|
109
|
-
case 'function':
|
|
110
|
-
return '[Function]';
|
|
111
|
-
default:
|
|
112
|
-
return '[object]';
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* `JSON.stringify` is TYPED to always return `string`, but a value it cannot
|
|
118
|
-
* represent (a function, a bare `undefined`) yields `undefined` at runtime. This
|
|
119
|
-
* boundary admits the absence the standard-library overload denies, so the guard
|
|
120
|
-
* below is a real check rather than a cast around one.
|
|
121
|
-
*/
|
|
122
|
-
function stringifyJson(value: unknown): string | undefined {
|
|
123
|
-
return JSON.stringify(value, null, 2);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* The value's pretty JSON for the clipboard. A value JSON cannot represent (a
|
|
128
|
-
* function, a bare `undefined`) has no JSON, so its readable form is copied
|
|
129
|
-
* rather than an empty string. A value JSON REFUSES (a `bigint`) throws here, and
|
|
130
|
-
* the caller renders that as the same visible alert a blocked write is.
|
|
131
|
-
*/
|
|
132
|
-
function serializeForCopy(value: unknown): string {
|
|
133
|
-
return stringifyJson(value) ?? String(value);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* A child's identity for the open-state map. Each segment is percent-encoded, so a
|
|
138
|
-
* key that itself contains the separator cannot collide with a different path.
|
|
139
|
-
*/
|
|
140
|
-
function childPath(parent: string, name: string): string {
|
|
141
|
-
const segment = encodeURIComponent(name);
|
|
142
|
-
return parent === '' ? segment : `${parent}/${segment}`;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/** The default open state a call site's `defaultExpanded` selects. */
|
|
146
|
-
type Baseline = 'depth' | 'expanded' | 'collapsed';
|
|
147
|
-
|
|
148
|
-
function initialBaseline(defaultExpanded: boolean | undefined): Baseline {
|
|
149
|
-
if (defaultExpanded === true) return 'expanded';
|
|
150
|
-
if (defaultExpanded === false) return 'collapsed';
|
|
151
|
-
return 'depth';
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* The set of paths EXPAND-ALL auto-opens: a breadth-first sweep that opens each
|
|
156
|
-
* container in turn — spending its visible child count against a shared node budget
|
|
157
|
-
* and enqueuing that page's own container children — skipping any node whose page
|
|
158
|
-
* would overspend {@link AUTO_EXPAND_NODE_BUDGET} or that sits past {@link MAX_AUTO_DEPTH}.
|
|
159
|
-
* Only a bounded window of a huge payload is materialized, so this stays cheap even
|
|
160
|
-
* when the data is enormous; the paths it omits stay collapsed and open on a click.
|
|
161
|
-
*/
|
|
162
|
-
function expandedOpenPaths(root: unknown): ReadonlySet<string> {
|
|
163
|
-
const open = new Set<string>();
|
|
164
|
-
if (!isContainer(root)) return open;
|
|
165
|
-
|
|
166
|
-
let budget = AUTO_EXPAND_NODE_BUDGET;
|
|
167
|
-
const queue: { readonly value: unknown; readonly path: string; readonly depth: number }[] = [
|
|
168
|
-
{ value: root, path: '', depth: 0 },
|
|
169
|
-
];
|
|
170
|
-
|
|
171
|
-
while (queue.length > 0) {
|
|
172
|
-
const node = queue.shift();
|
|
173
|
-
if (node === undefined) break;
|
|
174
|
-
if (node.depth >= MAX_AUTO_DEPTH) continue;
|
|
175
|
-
|
|
176
|
-
const shown = Math.min(PAGE_SIZE, containerCount(node.value));
|
|
177
|
-
// Skip when the budget can't seat a whole page (a later, smaller node may still fit).
|
|
178
|
-
if (shown > budget) continue;
|
|
179
|
-
budget -= shown;
|
|
180
|
-
open.add(node.path);
|
|
181
|
-
|
|
182
|
-
for (const [name, childValue] of sliceEntries(node.value, shown)) {
|
|
183
|
-
if (isContainer(childValue)) {
|
|
184
|
-
queue.push({ value: childValue, path: childPath(node.path, name), depth: node.depth + 1 });
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return open;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Whether a node is open, from the baseline and the reader's own toggles. An
|
|
194
|
-
* explicit toggle always wins; otherwise the baseline decides — the depth-guarded
|
|
195
|
-
* default opens through {@link AUTO_EXPAND_DEPTH}, expand-all opens the budgeted
|
|
196
|
-
* breadth-first set, collapse-all opens nothing.
|
|
197
|
-
*/
|
|
198
|
-
function computeOpen(
|
|
199
|
-
baseline: Baseline,
|
|
200
|
-
overrides: ReadonlyMap<string, boolean>,
|
|
201
|
-
expandedPaths: ReadonlySet<string> | null,
|
|
202
|
-
path: string,
|
|
203
|
-
depth: number,
|
|
204
|
-
): boolean {
|
|
205
|
-
const override = overrides.get(path);
|
|
206
|
-
if (override !== undefined) return override;
|
|
207
|
-
if (baseline === 'expanded') return expandedPaths?.has(path) ?? false;
|
|
208
|
-
if (baseline === 'collapsed') return false;
|
|
209
|
-
return depth <= AUTO_EXPAND_DEPTH;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
interface JsonTreeContextValue {
|
|
213
|
-
/** Whether the node at `path`/`depth` is open right now. */
|
|
214
|
-
readonly isOpen: (path: string, depth: number) => boolean;
|
|
215
|
-
/** Records the reader's explicit toggle of one node. */
|
|
216
|
-
readonly setOpen: (path: string, open: boolean) => void;
|
|
217
|
-
/** Copies a value's JSON, returning whether the write succeeded. */
|
|
218
|
-
readonly copy: (value: unknown) => Promise<boolean>;
|
|
219
|
-
readonly pageSize: number;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const JsonTreeContext = createContext<JsonTreeContextValue | null>(null);
|
|
223
|
-
|
|
224
|
-
/** The shared tree state; a subcomponent outside a `JsonTree` is a wiring error. */
|
|
225
|
-
function useJsonTreeContext(): JsonTreeContextValue {
|
|
226
|
-
const context = useContext(JsonTreeContext);
|
|
227
|
-
if (context === null) {
|
|
228
|
-
throw new Error('JsonTree subcomponents must be rendered inside a JsonTree.');
|
|
229
|
-
}
|
|
230
|
-
return context;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* One nesting level's indent: the child block insets and draws its own guide
|
|
235
|
-
* rail. The depth is expressed by the DOM nesting, so each level repeats this
|
|
236
|
-
* single step rather than computing an absolute offset.
|
|
237
|
-
*/
|
|
238
|
-
const childrenStyle: CSSProperties = {
|
|
239
|
-
paddingLeft: 'var(--tai-space-4)',
|
|
240
|
-
marginLeft: 'var(--tai-space-1)',
|
|
241
|
-
borderLeft: '1px solid var(--tai-color-decor)',
|
|
242
|
-
};
|
|
243
|
-
|
|
244
|
-
/** A `<summary>` is a click target; browsers do not style it as one by default. */
|
|
245
|
-
const summaryStyle: CSSProperties = {
|
|
246
|
-
display: 'flex',
|
|
247
|
-
alignItems: 'center',
|
|
248
|
-
gap: 'var(--tai-space-2)',
|
|
249
|
-
cursor: 'pointer',
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
/** The copy control sits at the far end of a disclosure's row. */
|
|
253
|
-
const nodeCopyStyle: CSSProperties = { marginLeft: 'auto' };
|
|
254
|
-
|
|
255
|
-
/**
|
|
256
|
-
* The per-node copy button's geometry: borrows `tai-icon-btn` for the focus ring,
|
|
257
|
-
* muted ink and hover, then shrinks to the code rhythm so the row stays dense.
|
|
258
|
-
*/
|
|
259
|
-
const nodeCopyButtonStyle: CSSProperties = {
|
|
260
|
-
width: 'auto',
|
|
261
|
-
height: 'auto',
|
|
262
|
-
padding: 'var(--tai-space-1)',
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
const showMoreStyle: CSSProperties = { marginTop: 'var(--tai-space-1)' };
|
|
266
|
-
|
|
267
|
-
/** The syntax class for a primitive's type; anything outside JSON reads as muted. */
|
|
268
|
-
function primitiveClass(value: unknown): string {
|
|
269
|
-
if (typeof value === 'string') return 'tai-syntax-string';
|
|
270
|
-
if (typeof value === 'number' || typeof value === 'bigint') return 'tai-syntax-number';
|
|
271
|
-
if (typeof value === 'boolean') return 'tai-syntax-bool';
|
|
272
|
-
if (value === null || value === undefined) return 'tai-syntax-null';
|
|
273
|
-
return 'tai-muted';
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
interface CopyButtonProps {
|
|
277
|
-
readonly value: unknown;
|
|
278
|
-
/**
|
|
279
|
-
* The button's resting accessible name. When it flips to its confirmed state the
|
|
280
|
-
* name flips with it, so a control reading "Copied" is never still named "Copy"
|
|
281
|
-
* (WCAG 2.5.3). A `text` button spells the name in its own words; an `icon` button
|
|
282
|
-
* takes it from here.
|
|
283
|
-
*/
|
|
284
|
-
readonly label: string;
|
|
285
|
-
readonly variant: 'text' | 'icon';
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
/**
|
|
289
|
-
* A copy control that writes its value to the clipboard and shows a transient
|
|
290
|
-
* confirmed state. The write itself lives on the tree context, so a refusal is
|
|
291
|
-
* reported ONCE — as the tree's shared alert — rather than inline at each of the
|
|
292
|
-
* many buttons a large payload carries.
|
|
293
|
-
*/
|
|
294
|
-
function CopyButton({ value, label, variant }: CopyButtonProps): ReactElement {
|
|
295
|
-
const { copy } = useJsonTreeContext();
|
|
296
|
-
const [copied, setCopied] = useState(false);
|
|
297
|
-
const resetTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
298
|
-
// The write is async, so a copy can be in flight when the button unmounts (a dialog
|
|
299
|
-
// holding the tree closes on the same click); checked before the resolution sets state.
|
|
300
|
-
const mounted = useRef(true);
|
|
301
|
-
|
|
302
|
-
useEffect(() => {
|
|
303
|
-
mounted.current = true;
|
|
304
|
-
return () => {
|
|
305
|
-
mounted.current = false;
|
|
306
|
-
if (resetTimer.current !== null) clearTimeout(resetTimer.current);
|
|
307
|
-
};
|
|
308
|
-
}, []);
|
|
309
|
-
|
|
310
|
-
const handleClick = (event: ReactMouseEvent<HTMLButtonElement>): void => {
|
|
311
|
-
// Inside a `<summary>` a click both toggles the disclosure natively and reaches
|
|
312
|
-
// the summary's own toggle handler; neither should fire for a copy.
|
|
313
|
-
event.preventDefault();
|
|
314
|
-
event.stopPropagation();
|
|
315
|
-
void copy(value).then((ok) => {
|
|
316
|
-
if (!ok || !mounted.current) return;
|
|
317
|
-
setCopied(true);
|
|
318
|
-
if (resetTimer.current !== null) clearTimeout(resetTimer.current);
|
|
319
|
-
resetTimer.current = setTimeout(() => {
|
|
320
|
-
if (mounted.current) setCopied(false);
|
|
321
|
-
}, COPIED_RESET_MS);
|
|
322
|
-
});
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
if (variant === 'text') {
|
|
326
|
-
return (
|
|
327
|
-
<button type="button" className="tai-btn tai-btn-ghost" onClick={handleClick}>
|
|
328
|
-
{copied ? <CheckIcon /> : <CopyIcon />}
|
|
329
|
-
{copied ? COPIED_LABEL : label}
|
|
330
|
-
</button>
|
|
331
|
-
);
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
return (
|
|
335
|
-
<button
|
|
336
|
-
type="button"
|
|
337
|
-
className="tai-icon-btn"
|
|
338
|
-
style={{ ...nodeCopyStyle, ...nodeCopyButtonStyle }}
|
|
339
|
-
aria-label={copied ? COPIED_LABEL : label}
|
|
340
|
-
onClick={handleClick}
|
|
341
|
-
>
|
|
342
|
-
{copied ? <CheckIcon /> : <CopyIcon />}
|
|
343
|
-
</button>
|
|
344
|
-
);
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
interface NodeProps {
|
|
348
|
-
readonly name?: string;
|
|
349
|
-
readonly value: unknown;
|
|
350
|
-
readonly depth: number;
|
|
351
|
-
readonly path: string;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/** A container's child count, without materializing its entries. */
|
|
355
|
-
function containerCount(value: unknown): number {
|
|
356
|
-
if (Array.isArray(value)) return value.length;
|
|
357
|
-
if (isRecord(value)) return Object.keys(value).length;
|
|
358
|
-
throw new Error('containerCount expects an array or a record.');
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
/**
|
|
362
|
-
* The first `end` entries of a container, arrays keyed by index and objects by
|
|
363
|
-
* key. Only the visible window is materialized, so a million-element array's
|
|
364
|
-
* children never all exist at once.
|
|
365
|
-
*/
|
|
366
|
-
function sliceEntries(value: unknown, end: number): [string, unknown][] {
|
|
367
|
-
if (Array.isArray(value)) {
|
|
368
|
-
return value.slice(0, end).map((item, index) => [String(index), item]);
|
|
369
|
-
}
|
|
370
|
-
// Slice the keys before reading values, so only the visible window is materialized.
|
|
371
|
-
if (isRecord(value))
|
|
372
|
-
return Object.keys(value)
|
|
373
|
-
.slice(0, end)
|
|
374
|
-
.map((key) => [key, value[key]]);
|
|
375
|
-
throw new Error('sliceEntries expects an array or a record.');
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
/** One container's summary text: its kind and its child count. */
|
|
379
|
-
function containerSummary(value: unknown, count: number): string {
|
|
380
|
-
return Array.isArray(value) ? `Array(${String(count)})` : `Object(${String(count)})`;
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* The visible slice of a container's children, plus a "show more" control while
|
|
385
|
-
* any remain. Rendered ONLY when the node is open, so a collapsed container costs
|
|
386
|
-
* nothing and the page count follows how far the reader has opened it.
|
|
387
|
-
*/
|
|
388
|
-
function NodeChildren({
|
|
389
|
-
value,
|
|
390
|
-
count,
|
|
391
|
-
depth,
|
|
392
|
-
path,
|
|
393
|
-
}: {
|
|
394
|
-
readonly value: unknown;
|
|
395
|
-
readonly count: number;
|
|
396
|
-
readonly depth: number;
|
|
397
|
-
readonly path: string;
|
|
398
|
-
}): ReactElement {
|
|
399
|
-
const { pageSize } = useJsonTreeContext();
|
|
400
|
-
const [visible, setVisible] = useState(pageSize);
|
|
401
|
-
const shownCount = Math.min(visible, count);
|
|
402
|
-
const shown = sliceEntries(value, shownCount);
|
|
403
|
-
const remaining = count - shownCount;
|
|
404
|
-
|
|
405
|
-
return (
|
|
406
|
-
<div style={childrenStyle}>
|
|
407
|
-
{shown.map(([childName, childValue]) => (
|
|
408
|
-
<JsonNode
|
|
409
|
-
key={childName}
|
|
410
|
-
name={childName}
|
|
411
|
-
value={childValue}
|
|
412
|
-
depth={depth + 1}
|
|
413
|
-
path={childPath(path, childName)}
|
|
414
|
-
/>
|
|
415
|
-
))}
|
|
416
|
-
{remaining > 0 ? (
|
|
417
|
-
<button
|
|
418
|
-
type="button"
|
|
419
|
-
className="tai-btn tai-btn-ghost"
|
|
420
|
-
style={showMoreStyle}
|
|
421
|
-
onClick={() => {
|
|
422
|
-
setVisible((current) => current + pageSize);
|
|
423
|
-
}}
|
|
424
|
-
>
|
|
425
|
-
Show {String(Math.min(remaining, pageSize))} more
|
|
426
|
-
</button>
|
|
427
|
-
) : null}
|
|
428
|
-
</div>
|
|
429
|
-
);
|
|
430
|
-
}
|
|
431
|
-
|
|
432
|
-
function JsonNode({ name, value, depth, path }: NodeProps): ReactElement {
|
|
433
|
-
const { isOpen, setOpen } = useJsonTreeContext();
|
|
434
|
-
|
|
435
|
-
if (isContainer(value)) {
|
|
436
|
-
const count = containerCount(value);
|
|
437
|
-
const open = isOpen(path, depth);
|
|
438
|
-
const summary = containerSummary(value, count);
|
|
439
|
-
const handleToggle = (event: ReactMouseEvent<HTMLElement>): void => {
|
|
440
|
-
// The disclosure is state-driven: cancel the browser's own toggle so the two
|
|
441
|
-
// never diverge, then record the reader's intent.
|
|
442
|
-
event.preventDefault();
|
|
443
|
-
setOpen(path, !open);
|
|
444
|
-
};
|
|
445
|
-
|
|
446
|
-
return (
|
|
447
|
-
<details open={open}>
|
|
448
|
-
<summary style={summaryStyle} onClick={handleToggle}>
|
|
449
|
-
{name !== undefined ? <span className="tai-syntax-key">{name}: </span> : null}
|
|
450
|
-
<span className="tai-muted">{summary}</span>
|
|
451
|
-
{/* The root's copy-node control would duplicate the toolbar's copy-whole. */}
|
|
452
|
-
{depth > 0 ? (
|
|
453
|
-
<CopyButton
|
|
454
|
-
value={value}
|
|
455
|
-
variant="icon"
|
|
456
|
-
label={name !== undefined ? `Copy ${name}` : COPY_LABEL}
|
|
457
|
-
/>
|
|
458
|
-
) : null}
|
|
459
|
-
</summary>
|
|
460
|
-
{open ? <NodeChildren value={value} count={count} depth={depth} path={path} /> : null}
|
|
461
|
-
</details>
|
|
462
|
-
);
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
return (
|
|
466
|
-
<div>
|
|
467
|
-
{name !== undefined ? <span className="tai-syntax-key">{name}: </span> : null}
|
|
468
|
-
<span className={primitiveClass(value)}>{primitiveText(value)}</span>
|
|
469
|
-
</div>
|
|
470
|
-
);
|
|
471
|
-
}
|
|
472
|
-
|
|
473
54
|
export function JsonTree({ data, defaultExpanded, label }: JsonTreeProps): ReactElement {
|
|
474
55
|
const [baseline, setBaseline] = useState<Baseline>(() => initialBaseline(defaultExpanded));
|
|
475
56
|
const [overrides, setOverrides] = useState<ReadonlyMap<string, boolean>>(() => new Map());
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formatting a JSON value for display and for the clipboard: the inline primitive
|
|
3
|
+
* text and its syntax class, the clipboard serialization, and the copy-failure
|
|
4
|
+
* messages.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Shown when the browser offers no clipboard at all (any non-secure context). */
|
|
8
|
+
export const NO_CLIPBOARD =
|
|
9
|
+
'This browser will not write to the clipboard here. Select the value and copy it by hand.';
|
|
10
|
+
|
|
11
|
+
/** Shown when the write, or the value's serialization, is offered and refused. */
|
|
12
|
+
export function copyFailed(reason: unknown): string {
|
|
13
|
+
const detail = reason instanceof Error ? reason.message : String(reason);
|
|
14
|
+
return `Copy failed: ${detail}.`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function primitiveText(value: unknown): string {
|
|
18
|
+
if (value === null) return 'null';
|
|
19
|
+
switch (typeof value) {
|
|
20
|
+
case 'undefined':
|
|
21
|
+
return 'undefined';
|
|
22
|
+
case 'string':
|
|
23
|
+
return `"${value}"`;
|
|
24
|
+
case 'number':
|
|
25
|
+
case 'bigint':
|
|
26
|
+
case 'boolean':
|
|
27
|
+
return String(value);
|
|
28
|
+
case 'symbol':
|
|
29
|
+
return value.toString();
|
|
30
|
+
case 'function':
|
|
31
|
+
return '[Function]';
|
|
32
|
+
default:
|
|
33
|
+
return '[object]';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** The syntax class for a primitive's type; anything outside JSON reads as muted. */
|
|
38
|
+
export function primitiveClass(value: unknown): string {
|
|
39
|
+
if (typeof value === 'string') return 'tai-syntax-string';
|
|
40
|
+
if (typeof value === 'number' || typeof value === 'bigint') return 'tai-syntax-number';
|
|
41
|
+
if (typeof value === 'boolean') return 'tai-syntax-bool';
|
|
42
|
+
if (value === null || value === undefined) return 'tai-syntax-null';
|
|
43
|
+
return 'tai-muted';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* `JSON.stringify` is TYPED to always return `string`, but a value it cannot
|
|
48
|
+
* represent (a function, a bare `undefined`) yields `undefined` at runtime. This
|
|
49
|
+
* boundary admits the absence the standard-library overload denies, so the guard
|
|
50
|
+
* below is a real check rather than a cast around one.
|
|
51
|
+
*/
|
|
52
|
+
function stringifyJson(value: unknown): string | undefined {
|
|
53
|
+
return JSON.stringify(value, null, 2);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The value's pretty JSON for the clipboard. A value JSON cannot represent (a
|
|
58
|
+
* function, a bare `undefined`) has no JSON, so its readable form is copied
|
|
59
|
+
* rather than an empty string. A value JSON REFUSES (a `bigint`) throws here, and
|
|
60
|
+
* the caller renders that as the same visible alert a blocked write is.
|
|
61
|
+
*/
|
|
62
|
+
export function serializeForCopy(value: unknown): string {
|
|
63
|
+
return stringifyJson(value) ?? String(value);
|
|
64
|
+
}
|