@d34dman/flowdrop 0.0.57 → 0.0.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +9 -8
  2. package/dist/adapters/WorkflowAdapter.d.ts +2 -1
  3. package/dist/adapters/agentspec/AgentSpecAdapter.d.ts +4 -0
  4. package/dist/adapters/agentspec/AgentSpecAdapter.js +27 -22
  5. package/dist/adapters/agentspec/componentTypeDefaults.d.ts +73 -0
  6. package/dist/adapters/agentspec/componentTypeDefaults.js +238 -0
  7. package/dist/adapters/agentspec/{nodeTypeRegistry.d.ts → defaultNodeTypes.d.ts} +21 -30
  8. package/dist/adapters/agentspec/{nodeTypeRegistry.js → defaultNodeTypes.js} +31 -59
  9. package/dist/adapters/agentspec/index.d.ts +3 -1
  10. package/dist/adapters/agentspec/index.js +4 -2
  11. package/dist/components/App.svelte +57 -13
  12. package/dist/components/NodeSidebar.svelte +20 -8
  13. package/dist/components/NodeSidebar.svelte.d.ts +2 -1
  14. package/dist/components/WorkflowEditor.svelte +14 -13
  15. package/dist/components/form/FormMarkdownEditor.svelte +546 -422
  16. package/dist/components/form/FormMarkdownEditor.svelte.d.ts +2 -0
  17. package/dist/components/form/FormUISchemaRenderer.svelte +4 -8
  18. package/dist/components/form/types.d.ts +1 -1
  19. package/dist/components/nodes/WorkflowNode.svelte +1 -2
  20. package/dist/core/index.d.ts +13 -3
  21. package/dist/core/index.js +16 -3
  22. package/dist/form/code.js +6 -1
  23. package/dist/form/fieldRegistry.d.ts +79 -15
  24. package/dist/form/fieldRegistry.js +104 -49
  25. package/dist/form/full.d.ts +2 -2
  26. package/dist/form/full.js +2 -2
  27. package/dist/form/index.d.ts +3 -3
  28. package/dist/form/index.js +6 -2
  29. package/dist/form/markdown.d.ts +3 -3
  30. package/dist/form/markdown.js +8 -4
  31. package/dist/index.d.ts +2 -2
  32. package/dist/index.js +2 -2
  33. package/dist/registry/BaseRegistry.d.ts +92 -0
  34. package/dist/registry/BaseRegistry.js +124 -0
  35. package/dist/registry/builtinFormats.d.ts +23 -0
  36. package/dist/registry/builtinFormats.js +70 -0
  37. package/dist/registry/builtinNodes.js +4 -0
  38. package/dist/registry/index.d.ts +2 -1
  39. package/dist/registry/index.js +2 -0
  40. package/dist/registry/nodeComponentRegistry.d.ts +26 -57
  41. package/dist/registry/nodeComponentRegistry.js +29 -82
  42. package/dist/registry/workflowFormatRegistry.d.ts +122 -0
  43. package/dist/registry/workflowFormatRegistry.js +96 -0
  44. package/dist/schema/index.d.ts +23 -0
  45. package/dist/schema/index.js +23 -0
  46. package/dist/schemas/v1/workflow.schema.json +1078 -0
  47. package/dist/stores/portCoordinateStore.js +1 -4
  48. package/dist/stores/workflowStore.d.ts +3 -0
  49. package/dist/stores/workflowStore.js +3 -0
  50. package/dist/svelte-app.d.ts +4 -0
  51. package/dist/svelte-app.js +9 -1
  52. package/dist/types/index.d.ts +18 -0
  53. package/dist/types/index.js +4 -0
  54. package/package.json +20 -13
@@ -21,6 +21,8 @@ interface Props {
21
21
  autosaveDelay?: number;
22
22
  /** Whether the field is disabled (read-only) */
23
23
  disabled?: boolean;
24
+ /** Whether to use dark theme */
25
+ darkTheme?: boolean;
24
26
  /** ARIA description ID */
25
27
  ariaDescribedBy?: string;
26
28
  /** Callback when value changes */
@@ -13,16 +13,12 @@
13
13
 
14
14
  <script lang="ts">
15
15
  import type { UISchemaElement } from '../../types/uischema.js';
16
- import type {
17
- ConfigSchema,
18
- WorkflowNode,
19
- WorkflowEdge,
20
- AuthProvider
21
- } from '../../types/index.js';
16
+ import type { ConfigSchema, WorkflowNode, WorkflowEdge, AuthProvider } from '../../types/index.js';
22
17
  import type { FieldSchema } from './types.js';
23
18
  import { resolveScopeToKey } from '../../utils/uischema.js';
24
19
  import FormField from './FormField.svelte';
25
20
  import FormFieldset from './FormFieldset.svelte';
21
+ import Self from './FormUISchemaRenderer.svelte';
26
22
 
27
23
  interface Props {
28
24
  /** The UISchema element to render */
@@ -92,7 +88,7 @@
92
88
  {:else if element.type === 'VerticalLayout'}
93
89
  <div class="form-uischema-layout form-uischema-layout--vertical">
94
90
  {#each element.elements as child, idx (idx)}
95
- <svelte:self
91
+ <Self
96
92
  element={child}
97
93
  {schema}
98
94
  {values}
@@ -112,7 +108,7 @@
112
108
  <FormFieldset group={element}>
113
109
  <div class="form-uischema-layout form-uischema-layout--vertical">
114
110
  {#each element.elements as child, idx (idx)}
115
- <svelte:self
111
+ <Self
116
112
  element={child}
117
113
  {schema}
118
114
  {values}
@@ -194,7 +194,7 @@ export interface CodeEditorFieldProps extends BaseFieldProps {
194
194
  onChange: (value: unknown) => void;
195
195
  }
196
196
  /**
197
- * Properties for markdown editor fields (SimpleMDE-based)
197
+ * Properties for markdown editor fields (CodeMirror 6-based)
198
198
  */
199
199
  export interface MarkdownEditorFieldProps extends BaseFieldProps {
200
200
  /** Current value (markdown string) */
@@ -195,8 +195,7 @@
195
195
  </h3>
196
196
 
197
197
  <!-- Status Indicators -->
198
- <div class="flowdrop-flex flowdrop-gap--2 flowdrop-items--center">
199
- </div>
198
+ <div class="flowdrop-flex flowdrop-gap--2 flowdrop-items--center"></div>
200
199
  </div>
201
200
  <!-- Node Description - line-height 20px so header grows in steps of 10 -->
202
201
  <p
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This module exports types, utilities, and lightweight functionality
5
5
  * with zero heavy dependencies. Safe to import without bundling
6
- * @xyflow/svelte, codemirror, easymde, or marked.
6
+ * @xyflow/svelte, codemirror, or marked.
7
7
  *
8
8
  * @module core
9
9
  *
@@ -14,13 +14,20 @@
14
14
  * import { getStatusColor, createDefaultExecutionInfo } from "@d34dman/flowdrop/core";
15
15
  * ```
16
16
  */
17
+ export type { WorkflowFormat, BuiltinWorkflowFormat } from '../types/index.js';
18
+ export { DEFAULT_WORKFLOW_FORMAT } from '../types/index.js';
17
19
  export type { NodeCategory, BuiltinNodeCategory, CategoryDefinition, NodeDataType, NodePort, DynamicPort, Branch, NodeMetadata, NodeExtensions, NodeUIExtensions, ConfigValues, WorkflowNode, WorkflowEdge, Workflow, ApiResponse, NodesResponse, WorkflowResponse, WorkflowsResponse, ExecutionStatus, ExecutionResult, FlowDropConfig, WorkflowEvents, BuiltinNodeType, PortConfig, PortCompatibilityRule, ConfigSchema, ConfigProperty, HttpMethod, DynamicSchemaEndpoint, ExternalEditLink, ConfigEditOptions, EdgeCategory, UISchemaElementType, UISchemaElementBase, UISchemaControl, UISchemaVerticalLayout, UISchemaGroup, UISchemaElement } from '../types/index.js';
18
20
  export { isUISchemaControl, isUISchemaVerticalLayout, isUISchemaGroup } from '../types/index.js';
19
21
  export type { WorkflowEditorConfig, EditorFeatures, UIConfig, APIConfig, ExecutionConfig, StorageConfig } from '../types/config.js';
20
22
  export type { AuthProvider, StaticAuthConfig, CallbackAuthConfig } from '../types/auth.js';
21
23
  export type { WorkflowChangeType, FlowDropEventHandlers, FlowDropFeatures } from '../types/events.js';
22
24
  export type { FieldSchema, FieldType, FieldFormat, FieldOption, SchemaFormProps, BaseFieldProps, TextFieldProps, TextareaFieldProps, NumberFieldProps, ToggleFieldProps, RangeFieldProps, SelectFieldProps, CheckboxGroupFieldProps, ArrayFieldProps, CodeEditorFieldProps, MarkdownEditorFieldProps, TemplateEditorFieldProps, FormFieldFactoryProps, FormFieldWrapperProps } from '../components/form/types.js';
23
- export type { NodeComponentProps, NodeComponentRegistration, NodeComponentCategory, StatusPosition, StatusSize, NodeRegistrationFilter, FlowDropPluginConfig, PluginNodeDefinition, PluginRegistrationResult } from '../registry/index.js';
25
+ export { BaseRegistry } from '../registry/BaseRegistry.js';
26
+ export type { NodeComponentProps, NodeTypeInfo, NodeComponentRegistration, NodeComponentCategory, StatusPosition, StatusSize, NodeRegistrationFilter, FlowDropPluginConfig, PluginNodeDefinition, PluginRegistrationResult } from '../registry/index.js';
27
+ export type { FieldMatcherRegistration } from '../form/fieldRegistry.js';
28
+ export { workflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
29
+ export type { WorkflowFormatAdapter, FormatValidationResult } from '../registry/workflowFormatRegistry.js';
30
+ export { registerBuiltinFormats, areBuiltinFormatsRegistered, resetBuiltinFormatRegistration } from '../registry/builtinFormats.js';
24
31
  export type { ToastType, ToastOptions } from '../services/toastService.js';
25
32
  export type { DynamicSchemaResult } from '../services/dynamicSchemaService.js';
26
33
  export type { PlaygroundSession, PlaygroundMessage, PlaygroundInputField, PlaygroundMessageRequest, PlaygroundMessagesResult, PlaygroundConfig, PlaygroundMode, PlaygroundSessionStatus, PlaygroundMessageRole, PlaygroundMessageLevel, PlaygroundMessageMetadata, PlaygroundApiResponse, PlaygroundSessionsResponse, PlaygroundSessionResponse, PlaygroundMessageResponse, PlaygroundMessagesApiResponse } from '../types/playground.js';
@@ -44,7 +51,9 @@ export { defaultEndpointConfig, createEndpointConfig } from '../config/endpoints
44
51
  export * from '../adapters/WorkflowAdapter.js';
45
52
  export type { AgentSpecNodeComponentType, AgentSpecToolComponentType, AgentSpecComponentType, AgentSpecProperty, AgentSpecNodeBase, AgentSpecStartNode, AgentSpecEndNode, AgentSpecLLMNode, AgentSpecAPINode, AgentSpecAgentNode, AgentSpecFlowNode, AgentSpecMapNode, AgentSpecBranchingNode, AgentSpecToolNode, AgentSpecNode, AgentSpecBranch, AgentSpecControlFlowEdge, AgentSpecDataFlowEdge, AgentSpecFlow, AgentSpecToolBase, AgentSpecServerTool, AgentSpecClientTool, AgentSpecRemoteTool, AgentSpecTool, AgentSpecLLMConfig, AgentSpecAgent, AgentSpecDocument } from '../types/agentspec.js';
46
53
  export { COMPONENT_REF_PREFIX, isComponentRef, extractComponentRefId, createComponentRef } from '../types/agentspec.js';
47
- export { getAgentSpecNodeMetadata, getAllAgentSpecNodeTypes, createAgentSpecNodeMetadata, isAgentSpecNodeId, extractComponentType, AGENTSPEC_NAMESPACE } from '../adapters/agentspec/nodeTypeRegistry.js';
54
+ export { getAgentSpecNodeMetadata, getDefaultAgentSpecNodeTypes, createAgentSpecNodeMetadata } from '../adapters/agentspec/defaultNodeTypes.js';
55
+ export { getComponentTypeDefaults, extractComponentType, isAgentSpecNodeId, AGENTSPEC_NAMESPACE } from '../adapters/agentspec/componentTypeDefaults.js';
56
+ export type { ComponentTypeDefaults } from '../adapters/agentspec/componentTypeDefaults.js';
48
57
  export { AgentSpecAdapter } from '../adapters/agentspec/AgentSpecAdapter.js';
49
58
  export { AgentSpecAgentAdapter } from '../adapters/agentspec/agentAdapter.js';
50
59
  export type { AgentConfig, AgentSpecImportResult } from '../adapters/agentspec/agentAdapter.js';
@@ -56,5 +65,6 @@ export type { AgentSpecEndpointConfig } from '../config/agentSpecEndpoints.js';
56
65
  export { defaultAgentSpecEndpoints, createAgentSpecEndpointConfig, buildAgentSpecUrl, getAgentSpecAuthHeaders } from '../config/agentSpecEndpoints.js';
57
66
  export { AgentSpecExecutionService, agentSpecExecutionService } from '../services/agentSpecExecutionService.js';
58
67
  export type { AgentSpecExecutionHandle } from '../services/agentSpecExecutionService.js';
68
+ export { workflowSchema, WORKFLOW_SCHEMA_VERSION } from '../schema/index.js';
59
69
  export type { ThemePreference, ResolvedTheme } from '../stores/settingsStore.js';
60
70
  export { theme, resolvedTheme, setTheme, toggleTheme, cycleTheme, initializeTheme, isThemeInitialized } from '../stores/settingsStore.js';
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * This module exports types, utilities, and lightweight functionality
5
5
  * with zero heavy dependencies. Safe to import without bundling
6
- * @xyflow/svelte, codemirror, easymde, or marked.
6
+ * @xyflow/svelte, codemirror, or marked.
7
7
  *
8
8
  * @module core
9
9
  *
@@ -14,7 +14,14 @@
14
14
  * import { getStatusColor, createDefaultExecutionInfo } from "@d34dman/flowdrop/core";
15
15
  * ```
16
16
  */
17
+ export { DEFAULT_WORKFLOW_FORMAT } from '../types/index.js';
17
18
  export { isUISchemaControl, isUISchemaVerticalLayout, isUISchemaGroup } from '../types/index.js';
19
+ // Base registry
20
+ export { BaseRegistry } from '../registry/BaseRegistry.js';
21
+ // Workflow format registry
22
+ export { workflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
23
+ // Built-in format registration helpers
24
+ export { registerBuiltinFormats, areBuiltinFormatsRegistered, resetBuiltinFormatRegistration } from '../registry/builtinFormats.js';
18
25
  export { isChatInputNode, CHAT_INPUT_PATTERNS } from '../types/playground.js';
19
26
  // ============================================================================
20
27
  // Authentication Providers (no dependencies)
@@ -55,8 +62,10 @@ export { defaultEndpointConfig, createEndpointConfig } from '../config/endpoints
55
62
  // ============================================================================
56
63
  export * from '../adapters/WorkflowAdapter.js';
57
64
  export { COMPONENT_REF_PREFIX, isComponentRef, extractComponentRefId, createComponentRef } from '../types/agentspec.js';
58
- // Agent Spec node type registry
59
- export { getAgentSpecNodeMetadata, getAllAgentSpecNodeTypes, createAgentSpecNodeMetadata, isAgentSpecNodeId, extractComponentType, AGENTSPEC_NAMESPACE } from '../adapters/agentspec/nodeTypeRegistry.js';
65
+ // Agent Spec default node types (optional starter templates — users can provide their own)
66
+ export { getAgentSpecNodeMetadata, getDefaultAgentSpecNodeTypes, createAgentSpecNodeMetadata } from '../adapters/agentspec/defaultNodeTypes.js';
67
+ // Agent Spec component type defaults (adapter infrastructure)
68
+ export { getComponentTypeDefaults, extractComponentType, isAgentSpecNodeId, AGENTSPEC_NAMESPACE } from '../adapters/agentspec/componentTypeDefaults.js';
60
69
  // Agent Spec adapter (bidirectional conversion)
61
70
  export { AgentSpecAdapter } from '../adapters/agentspec/AgentSpecAdapter.js';
62
71
  // Agent Spec agent-level adapter
@@ -68,4 +77,8 @@ export { computeAutoLayout } from '../adapters/agentspec/autoLayout.js';
68
77
  export { defaultAgentSpecEndpoints, createAgentSpecEndpointConfig, buildAgentSpecUrl, getAgentSpecAuthHeaders } from '../config/agentSpecEndpoints.js';
69
78
  // Agent Spec execution service
70
79
  export { AgentSpecExecutionService, agentSpecExecutionService } from '../services/agentSpecExecutionService.js';
80
+ // ============================================================================
81
+ // Workflow JSON Schema
82
+ // ============================================================================
83
+ export { workflowSchema, WORKFLOW_SCHEMA_VERSION } from '../schema/index.js';
71
84
  export { theme, resolvedTheme, setTheme, toggleTheme, cycleTheme, initializeTheme, isThemeInitialized } from '../stores/settingsStore.js';
package/dist/form/code.js CHANGED
@@ -20,7 +20,7 @@
20
20
  * // Now SchemaForm will render code editors for format: "json", "code", or "template"
21
21
  * ```
22
22
  */
23
- import { registerFieldComponent } from './fieldRegistry.js';
23
+ import { registerFieldComponent, fieldComponentRegistry } from './fieldRegistry.js';
24
24
  // Re-export the components for direct usage if needed
25
25
  export { default as FormCodeEditor } from '../components/form/FormCodeEditor.svelte';
26
26
  export { default as FormTemplateEditor } from '../components/form/FormTemplateEditor.svelte';
@@ -54,6 +54,11 @@ let codeEditorRegistered = false;
54
54
  * Track if template editor is registered
55
55
  */
56
56
  let templateEditorRegistered = false;
57
+ // Sync registration flags with registry.clear() for test isolation
58
+ fieldComponentRegistry.onClear(() => {
59
+ codeEditorRegistered = false;
60
+ templateEditorRegistered = false;
61
+ });
57
62
  /**
58
63
  * Register the code/JSON editor field component
59
64
  *
@@ -6,9 +6,11 @@
6
6
  * - Dynamic field types: Users can add custom field renderers
7
7
  * - Lazy loading: Components can be registered at runtime
8
8
  *
9
+ * Extends BaseRegistry for shared mechanics (subscribe, onClear, etc.).
10
+ *
9
11
  * @module form/fieldRegistry
10
12
  *
11
- * @example Basic usage with light fields only (no codemirror/easymde):
13
+ * @example Basic usage with light fields only (no codemirror):
12
14
  * ```typescript
13
15
  * import { SchemaForm } from "@d34dman/flowdrop/form";
14
16
  * // Uses only basic fields - small bundle size
@@ -24,6 +26,7 @@
24
26
  */
25
27
  import type { Component } from 'svelte';
26
28
  import type { FieldSchema } from '../components/form/types.js';
29
+ import { BaseRegistry } from '../registry/BaseRegistry.js';
27
30
  /**
28
31
  * Base field component props that all registered field components should accept.
29
32
  * Components may have additional specific props.
@@ -54,18 +57,65 @@ export type FieldMatcher = (schema: FieldSchema) => boolean;
54
57
  */
55
58
  export type FieldComponent = Component<any, any, any>;
56
59
  /**
57
- * Registration entry for a field component
60
+ * Framework-agnostic matcher registration (no Svelte dependency).
61
+ * Contains the matching logic and priority without the component.
58
62
  */
59
- export interface FieldComponentRegistration {
60
- /** The Svelte component to render */
61
- component: FieldComponent;
62
- /** Function to determine if this component should handle a given schema */
63
+ export interface FieldMatcherRegistration {
64
+ /** Function to determine if this registration should handle a given schema */
63
65
  matcher: FieldMatcher;
64
66
  /** Priority for matching (higher = checked first) */
65
67
  priority: number;
66
68
  }
67
69
  /**
68
- * Register a field component for a specific field type
70
+ * Full registration entry for a field component.
71
+ * Extends FieldMatcherRegistration with the Svelte component needed for rendering.
72
+ */
73
+ export interface FieldComponentRegistration extends FieldMatcherRegistration {
74
+ /** The Svelte component to render */
75
+ component: FieldComponent;
76
+ }
77
+ /**
78
+ * Class-based field component registry.
79
+ * Extends BaseRegistry with priority-based field resolution.
80
+ */
81
+ declare class FieldComponentRegistry extends BaseRegistry<string, FieldComponentRegistration> {
82
+ /** Cached ordered keys by priority (highest first), invalidated on mutation */
83
+ private orderedKeys;
84
+ /**
85
+ * Register a field component.
86
+ * Silently overwrites existing registrations (preserves legacy behavior).
87
+ *
88
+ * @param type - Unique identifier for this field type
89
+ * @param registration - The field component registration
90
+ */
91
+ register(type: string, registration: FieldComponentRegistration): void;
92
+ /**
93
+ * Override unregister to invalidate the priority cache.
94
+ */
95
+ unregister(key: string): boolean;
96
+ /**
97
+ * Override clear to invalidate the priority cache.
98
+ */
99
+ clear(): void;
100
+ /**
101
+ * Resolve which component should render a given field schema.
102
+ * Checks registered matchers in priority order (highest first).
103
+ *
104
+ * @param schema - The field schema to resolve
105
+ * @returns The matching registration or null if no match
106
+ */
107
+ resolveFieldComponent(schema: FieldSchema): FieldComponentRegistration | null;
108
+ /**
109
+ * Get keys ordered by priority (cached).
110
+ */
111
+ private getOrderedKeys;
112
+ }
113
+ /** Singleton instance of the field component registry */
114
+ export declare const fieldComponentRegistry: FieldComponentRegistry;
115
+ /**
116
+ * Register a field component for a specific field type.
117
+ *
118
+ * @deprecated Use `fieldComponentRegistry.register()` instead.
69
119
  *
70
120
  * @param type - Unique identifier for this field type
71
121
  * @param component - Svelte component to render for matching fields
@@ -84,40 +134,53 @@ export interface FieldComponentRegistration {
84
134
  */
85
135
  export declare function registerFieldComponent(type: string, component: FieldComponent, matcher: FieldMatcher, priority?: number): void;
86
136
  /**
87
- * Unregister a field component
137
+ * Unregister a field component.
138
+ *
139
+ * @deprecated Use `fieldComponentRegistry.unregister()` instead.
88
140
  *
89
141
  * @param type - The field type to unregister
90
142
  * @returns true if the component was registered and removed
91
143
  */
92
144
  export declare function unregisterFieldComponent(type: string): boolean;
93
145
  /**
94
- * Get all registered field types
146
+ * Get all registered field types.
147
+ *
148
+ * @deprecated Use `fieldComponentRegistry.getKeys()` instead.
95
149
  *
96
150
  * @returns Array of registered field type identifiers
97
151
  */
98
152
  export declare function getRegisteredFieldTypes(): string[];
99
153
  /**
100
- * Check if a field type is registered
154
+ * Check if a field type is registered.
155
+ *
156
+ * @deprecated Use `fieldComponentRegistry.has()` instead.
101
157
  *
102
158
  * @param type - Field type to check
103
159
  * @returns true if the type is registered
104
160
  */
105
161
  export declare function isFieldTypeRegistered(type: string): boolean;
106
162
  /**
107
- * Resolve which component should render a given field schema
108
- * Checks registered matchers in priority order
163
+ * Resolve which component should render a given field schema.
164
+ * Checks registered matchers in priority order.
165
+ *
166
+ * @deprecated Use `fieldComponentRegistry.resolveFieldComponent()` instead.
109
167
  *
110
168
  * @param schema - The field schema to resolve
111
169
  * @returns The matching registration or null if no match
112
170
  */
113
171
  export declare function resolveFieldComponent(schema: FieldSchema): FieldComponentRegistration | null;
114
172
  /**
115
- * Clear all registered field components
116
- * Useful for testing or reset scenarios
173
+ * Clear all registered field components.
174
+ * Useful for testing or reset scenarios.
175
+ *
176
+ * @deprecated Use `fieldComponentRegistry.clear()` instead.
117
177
  */
118
178
  export declare function clearFieldRegistry(): void;
119
179
  /**
120
- * Get the registry size
180
+ * Get the registry size.
181
+ *
182
+ * @deprecated Use `fieldComponentRegistry.size` instead.
183
+ *
121
184
  * @returns Number of registered field components
122
185
  */
123
186
  export declare function getFieldRegistrySize(): number;
@@ -177,3 +240,4 @@ export declare const arrayMatcher: FieldMatcher;
177
240
  * Matches when format is "autocomplete" and autocomplete config with URL is provided
178
241
  */
179
242
  export declare const autocompleteMatcher: FieldMatcher;
243
+ export {};
@@ -6,9 +6,11 @@
6
6
  * - Dynamic field types: Users can add custom field renderers
7
7
  * - Lazy loading: Components can be registered at runtime
8
8
  *
9
+ * Extends BaseRegistry for shared mechanics (subscribe, onClear, etc.).
10
+ *
9
11
  * @module form/fieldRegistry
10
12
  *
11
- * @example Basic usage with light fields only (no codemirror/easymde):
13
+ * @example Basic usage with light fields only (no codemirror):
12
14
  * ```typescript
13
15
  * import { SchemaForm } from "@d34dman/flowdrop/form";
14
16
  * // Uses only basic fields - small bundle size
@@ -22,18 +24,82 @@
22
24
  * registerFieldComponent("code-editor", FormCodeEditor, codeEditorFieldMatcher);
23
25
  * ```
24
26
  */
27
+ import { BaseRegistry } from '../registry/BaseRegistry.js';
25
28
  /**
26
- * Field component registry
27
- * Stores registered field components with their matchers
28
- */
29
- const fieldRegistry = new Map();
30
- /**
31
- * Ordered list of field type keys by priority (highest first)
32
- * Cached and invalidated when registry changes
29
+ * Class-based field component registry.
30
+ * Extends BaseRegistry with priority-based field resolution.
33
31
  */
34
- let orderedKeys = null;
32
+ class FieldComponentRegistry extends BaseRegistry {
33
+ /** Cached ordered keys by priority (highest first), invalidated on mutation */
34
+ orderedKeys = null;
35
+ /**
36
+ * Register a field component.
37
+ * Silently overwrites existing registrations (preserves legacy behavior).
38
+ *
39
+ * @param type - Unique identifier for this field type
40
+ * @param registration - The field component registration
41
+ */
42
+ register(type, registration) {
43
+ this.items.set(type, registration);
44
+ this.orderedKeys = null;
45
+ this.notifyListeners();
46
+ }
47
+ /**
48
+ * Override unregister to invalidate the priority cache.
49
+ */
50
+ unregister(key) {
51
+ const result = super.unregister(key);
52
+ if (result) {
53
+ this.orderedKeys = null;
54
+ }
55
+ return result;
56
+ }
57
+ /**
58
+ * Override clear to invalidate the priority cache.
59
+ */
60
+ clear() {
61
+ super.clear();
62
+ this.orderedKeys = null;
63
+ }
64
+ /**
65
+ * Resolve which component should render a given field schema.
66
+ * Checks registered matchers in priority order (highest first).
67
+ *
68
+ * @param schema - The field schema to resolve
69
+ * @returns The matching registration or null if no match
70
+ */
71
+ resolveFieldComponent(schema) {
72
+ const keys = this.getOrderedKeys();
73
+ for (const key of keys) {
74
+ const registration = this.items.get(key);
75
+ if (registration && registration.matcher(schema)) {
76
+ return registration;
77
+ }
78
+ }
79
+ return null;
80
+ }
81
+ /**
82
+ * Get keys ordered by priority (cached).
83
+ */
84
+ getOrderedKeys() {
85
+ if (this.orderedKeys === null) {
86
+ this.orderedKeys = Array.from(this.items.entries())
87
+ .sort((a, b) => b[1].priority - a[1].priority)
88
+ .map(([key]) => key);
89
+ }
90
+ return this.orderedKeys;
91
+ }
92
+ }
93
+ /** Singleton instance of the field component registry */
94
+ export const fieldComponentRegistry = new FieldComponentRegistry();
95
+ // ============================================================================
96
+ // Backward-compatible function exports
97
+ // These delegate to the singleton and preserve the existing public API.
98
+ // ============================================================================
35
99
  /**
36
- * Register a field component for a specific field type
100
+ * Register a field component for a specific field type.
101
+ *
102
+ * @deprecated Use `fieldComponentRegistry.register()` instead.
37
103
  *
38
104
  * @param type - Unique identifier for this field type
39
105
  * @param component - Svelte component to render for matching fields
@@ -51,81 +117,70 @@ let orderedKeys = null;
51
117
  * ```
52
118
  */
53
119
  export function registerFieldComponent(type, component, matcher, priority = 0) {
54
- fieldRegistry.set(type, { component, matcher, priority });
55
- orderedKeys = null; // Invalidate cache
120
+ fieldComponentRegistry.register(type, { component, matcher, priority });
56
121
  }
57
122
  /**
58
- * Unregister a field component
123
+ * Unregister a field component.
124
+ *
125
+ * @deprecated Use `fieldComponentRegistry.unregister()` instead.
59
126
  *
60
127
  * @param type - The field type to unregister
61
128
  * @returns true if the component was registered and removed
62
129
  */
63
130
  export function unregisterFieldComponent(type) {
64
- const removed = fieldRegistry.delete(type);
65
- if (removed) {
66
- orderedKeys = null; // Invalidate cache
67
- }
68
- return removed;
131
+ return fieldComponentRegistry.unregister(type);
69
132
  }
70
133
  /**
71
- * Get all registered field types
134
+ * Get all registered field types.
135
+ *
136
+ * @deprecated Use `fieldComponentRegistry.getKeys()` instead.
72
137
  *
73
138
  * @returns Array of registered field type identifiers
74
139
  */
75
140
  export function getRegisteredFieldTypes() {
76
- return Array.from(fieldRegistry.keys());
141
+ return fieldComponentRegistry.getKeys();
77
142
  }
78
143
  /**
79
- * Check if a field type is registered
144
+ * Check if a field type is registered.
145
+ *
146
+ * @deprecated Use `fieldComponentRegistry.has()` instead.
80
147
  *
81
148
  * @param type - Field type to check
82
149
  * @returns true if the type is registered
83
150
  */
84
151
  export function isFieldTypeRegistered(type) {
85
- return fieldRegistry.has(type);
86
- }
87
- /**
88
- * Get ordered keys by priority (cached)
89
- */
90
- function getOrderedKeys() {
91
- if (orderedKeys === null) {
92
- orderedKeys = Array.from(fieldRegistry.entries())
93
- .sort((a, b) => b[1].priority - a[1].priority)
94
- .map(([key]) => key);
95
- }
96
- return orderedKeys;
152
+ return fieldComponentRegistry.has(type);
97
153
  }
98
154
  /**
99
- * Resolve which component should render a given field schema
100
- * Checks registered matchers in priority order
155
+ * Resolve which component should render a given field schema.
156
+ * Checks registered matchers in priority order.
157
+ *
158
+ * @deprecated Use `fieldComponentRegistry.resolveFieldComponent()` instead.
101
159
  *
102
160
  * @param schema - The field schema to resolve
103
161
  * @returns The matching registration or null if no match
104
162
  */
105
163
  export function resolveFieldComponent(schema) {
106
- const keys = getOrderedKeys();
107
- for (const key of keys) {
108
- const registration = fieldRegistry.get(key);
109
- if (registration && registration.matcher(schema)) {
110
- return registration;
111
- }
112
- }
113
- return null;
164
+ return fieldComponentRegistry.resolveFieldComponent(schema);
114
165
  }
115
166
  /**
116
- * Clear all registered field components
117
- * Useful for testing or reset scenarios
167
+ * Clear all registered field components.
168
+ * Useful for testing or reset scenarios.
169
+ *
170
+ * @deprecated Use `fieldComponentRegistry.clear()` instead.
118
171
  */
119
172
  export function clearFieldRegistry() {
120
- fieldRegistry.clear();
121
- orderedKeys = null;
173
+ fieldComponentRegistry.clear();
122
174
  }
123
175
  /**
124
- * Get the registry size
176
+ * Get the registry size.
177
+ *
178
+ * @deprecated Use `fieldComponentRegistry.size` instead.
179
+ *
125
180
  * @returns Number of registered field components
126
181
  */
127
182
  export function getFieldRegistrySize() {
128
- return fieldRegistry.size;
183
+ return fieldComponentRegistry.size;
129
184
  }
130
185
  // ============================================================================
131
186
  // Built-in Field Matchers (for light fields)
@@ -2,7 +2,7 @@
2
2
  * FlowDrop Form Full Module
3
3
  *
4
4
  * Convenience module that imports and registers all form field types,
5
- * including heavy editors (CodeMirror, EasyMDE).
5
+ * including heavy editors (CodeMirror).
6
6
  *
7
7
  * This is equivalent to importing from the light form module and manually
8
8
  * registering all editor types.
@@ -32,7 +32,7 @@ export { registerMarkdownEditorField, isMarkdownEditorRegistered, markdownEditor
32
32
  * This includes:
33
33
  * - Code/JSON editor (CodeMirror)
34
34
  * - Template editor (CodeMirror with Twig/Liquid syntax)
35
- * - Markdown editor (EasyMDE)
35
+ * - Markdown editor (CodeMirror 6)
36
36
  *
37
37
  * @example
38
38
  * ```typescript
package/dist/form/full.js CHANGED
@@ -2,7 +2,7 @@
2
2
  * FlowDrop Form Full Module
3
3
  *
4
4
  * Convenience module that imports and registers all form field types,
5
- * including heavy editors (CodeMirror, EasyMDE).
5
+ * including heavy editors (CodeMirror).
6
6
  *
7
7
  * This is equivalent to importing from the light form module and manually
8
8
  * registering all editor types.
@@ -42,7 +42,7 @@ let allFieldTypesInitialized = false;
42
42
  * This includes:
43
43
  * - Code/JSON editor (CodeMirror)
44
44
  * - Template editor (CodeMirror with Twig/Liquid syntax)
45
- * - Markdown editor (EasyMDE)
45
+ * - Markdown editor (CodeMirror 6)
46
46
  *
47
47
  * @example
48
48
  * ```typescript
@@ -6,7 +6,7 @@
6
6
  * only basic field types (text, number, select, checkbox, etc.).
7
7
  *
8
8
  * For code editor support (CodeMirror), import from "@d34dman/flowdrop/form/code"
9
- * For markdown editor support (EasyMDE), import from "@d34dman/flowdrop/form/markdown"
9
+ * For markdown editor support (CodeMirror 6), import from "@d34dman/flowdrop/form/markdown"
10
10
  *
11
11
  * @module form
12
12
  *
@@ -73,5 +73,5 @@ export { default as FormFieldset } from '../components/form/FormFieldset.svelte'
73
73
  export { default as FormUISchemaRenderer } from '../components/form/FormUISchemaRenderer.svelte';
74
74
  export type { FieldSchema, FieldType, FieldFormat, FieldOption, OneOfItem, SchemaFormProps, BaseFieldProps, TextFieldProps, TextareaFieldProps, NumberFieldProps, ToggleFieldProps, RangeFieldProps, SelectFieldProps, CheckboxGroupFieldProps, ArrayFieldProps, FormFieldFactoryProps, FormFieldWrapperProps } from '../components/form/types.js';
75
75
  export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, getSchemaOptions } from '../components/form/types.js';
76
- export { registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
77
- export type { FieldComponentProps, FieldMatcher, FieldComponent, FieldComponentRegistration } from './fieldRegistry.js';
76
+ export { fieldComponentRegistry, registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize, hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
77
+ export type { FieldComponentProps, FieldMatcher, FieldMatcherRegistration, FieldComponent, FieldComponentRegistration } from './fieldRegistry.js';
@@ -6,7 +6,7 @@
6
6
  * only basic field types (text, number, select, checkbox, etc.).
7
7
  *
8
8
  * For code editor support (CodeMirror), import from "@d34dman/flowdrop/form/code"
9
- * For markdown editor support (EasyMDE), import from "@d34dman/flowdrop/form/markdown"
9
+ * For markdown editor support (CodeMirror 6), import from "@d34dman/flowdrop/form/markdown"
10
10
  *
11
11
  * @module form
12
12
  *
@@ -84,6 +84,10 @@ export { isFieldOptionArray, isOneOfArray, normalizeOptions, oneOfToOptions, get
84
84
  // ============================================================================
85
85
  // Field Registry (for dynamic field registration)
86
86
  // ============================================================================
87
- export { registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize,
87
+ export {
88
+ // Registry singleton
89
+ fieldComponentRegistry,
90
+ // Backward-compatible function wrappers
91
+ registerFieldComponent, unregisterFieldComponent, resolveFieldComponent, getRegisteredFieldTypes, isFieldTypeRegistered, clearFieldRegistry, getFieldRegistrySize,
88
92
  // Built-in matchers for custom components
89
93
  hiddenFieldMatcher, checkboxGroupMatcher, enumSelectMatcher, textareaMatcher, rangeMatcher, textFieldMatcher, numberFieldMatcher, toggleMatcher, selectOptionsMatcher, arrayMatcher } from './fieldRegistry.js';
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * FlowDrop Form Markdown Editor Module
3
3
  *
4
- * Adds EasyMDE-based markdown editor support to SchemaForm.
5
- * This module bundles EasyMDE dependencies (~200KB).
4
+ * Adds CodeMirror 6-based markdown editor support to SchemaForm.
5
+ * Uses @codemirror/lang-markdown for syntax highlighting and marked for preview.
6
6
  *
7
7
  * @module form/markdown
8
8
  *
@@ -35,7 +35,7 @@ export declare function markdownEditorFieldMatcher(schema: FieldSchema): boolean
35
35
  * Register the markdown editor field component
36
36
  *
37
37
  * Call this function once at application startup to enable
38
- * markdown editor fields in SchemaForm. This loads EasyMDE dependencies.
38
+ * markdown editor fields in SchemaForm.
39
39
  *
40
40
  * @param priority - Priority for field matching (default: 100)
41
41
  *