@seed-ship/mcp-ui-solid 2.0.0 → 2.1.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.
Files changed (140) hide show
  1. package/README.md +50 -1
  2. package/dist/components/AutocompleteDropdown.cjs +201 -0
  3. package/dist/components/AutocompleteDropdown.cjs.map +1 -0
  4. package/dist/components/AutocompleteDropdown.d.ts +71 -0
  5. package/dist/components/AutocompleteDropdown.d.ts.map +1 -0
  6. package/dist/components/AutocompleteDropdown.js +201 -0
  7. package/dist/components/AutocompleteDropdown.js.map +1 -0
  8. package/dist/components/AutocompleteFormField.cjs +289 -0
  9. package/dist/components/AutocompleteFormField.cjs.map +1 -0
  10. package/dist/components/AutocompleteFormField.d.ts +52 -0
  11. package/dist/components/AutocompleteFormField.d.ts.map +1 -0
  12. package/dist/components/AutocompleteFormField.js +289 -0
  13. package/dist/components/AutocompleteFormField.js.map +1 -0
  14. package/dist/components/DraggableGridItem.cjs +133 -0
  15. package/dist/components/DraggableGridItem.cjs.map +1 -0
  16. package/dist/components/DraggableGridItem.d.ts +95 -0
  17. package/dist/components/DraggableGridItem.d.ts.map +1 -0
  18. package/dist/components/DraggableGridItem.js +133 -0
  19. package/dist/components/DraggableGridItem.js.map +1 -0
  20. package/dist/components/EditableUIResourceRenderer.cjs +203 -0
  21. package/dist/components/EditableUIResourceRenderer.cjs.map +1 -0
  22. package/dist/components/EditableUIResourceRenderer.d.ts +43 -0
  23. package/dist/components/EditableUIResourceRenderer.d.ts.map +1 -0
  24. package/dist/components/EditableUIResourceRenderer.js +203 -0
  25. package/dist/components/EditableUIResourceRenderer.js.map +1 -0
  26. package/dist/components/GhostText.cjs +105 -0
  27. package/dist/components/GhostText.cjs.map +1 -0
  28. package/dist/components/GhostText.d.ts +113 -0
  29. package/dist/components/GhostText.d.ts.map +1 -0
  30. package/dist/components/GhostText.js +105 -0
  31. package/dist/components/GhostText.js.map +1 -0
  32. package/dist/components/ResizeHandle.cjs +173 -0
  33. package/dist/components/ResizeHandle.cjs.map +1 -0
  34. package/dist/components/ResizeHandle.d.ts +50 -0
  35. package/dist/components/ResizeHandle.d.ts.map +1 -0
  36. package/dist/components/ResizeHandle.js +173 -0
  37. package/dist/components/ResizeHandle.js.map +1 -0
  38. package/dist/context/AutocompleteContext.cjs +158 -0
  39. package/dist/context/AutocompleteContext.cjs.map +1 -0
  40. package/dist/context/AutocompleteContext.d.ts +77 -0
  41. package/dist/context/AutocompleteContext.d.ts.map +1 -0
  42. package/dist/context/AutocompleteContext.js +158 -0
  43. package/dist/context/AutocompleteContext.js.map +1 -0
  44. package/dist/hooks/index.d.ts +6 -0
  45. package/dist/hooks/index.d.ts.map +1 -1
  46. package/dist/hooks/useAutocomplete.cjs +234 -0
  47. package/dist/hooks/useAutocomplete.cjs.map +1 -0
  48. package/dist/hooks/useAutocomplete.d.ts +119 -0
  49. package/dist/hooks/useAutocomplete.d.ts.map +1 -0
  50. package/dist/hooks/useAutocomplete.js +234 -0
  51. package/dist/hooks/useAutocomplete.js.map +1 -0
  52. package/dist/hooks/useDragDrop.cjs +170 -0
  53. package/dist/hooks/useDragDrop.cjs.map +1 -0
  54. package/dist/hooks/useDragDrop.d.ts +100 -0
  55. package/dist/hooks/useDragDrop.d.ts.map +1 -0
  56. package/dist/hooks/useDragDrop.js +170 -0
  57. package/dist/hooks/useDragDrop.js.map +1 -0
  58. package/dist/hooks/useResize.cjs +209 -0
  59. package/dist/hooks/useResize.cjs.map +1 -0
  60. package/dist/hooks/useResize.d.ts +87 -0
  61. package/dist/hooks/useResize.d.ts.map +1 -0
  62. package/dist/hooks/useResize.js +209 -0
  63. package/dist/hooks/useResize.js.map +1 -0
  64. package/dist/hooks.cjs +6 -0
  65. package/dist/hooks.cjs.map +1 -1
  66. package/dist/hooks.d.cts +6 -0
  67. package/dist/hooks.d.ts +6 -0
  68. package/dist/hooks.js +6 -0
  69. package/dist/hooks.js.map +1 -1
  70. package/dist/index.cjs +29 -0
  71. package/dist/index.cjs.map +1 -1
  72. package/dist/index.d.cts +18 -3
  73. package/dist/index.d.ts +18 -3
  74. package/dist/index.d.ts.map +1 -1
  75. package/dist/index.js +29 -0
  76. package/dist/index.js.map +1 -1
  77. package/dist/plugins/duckdb.cjs +192 -0
  78. package/dist/plugins/duckdb.cjs.map +1 -0
  79. package/dist/plugins/duckdb.d.ts +20 -0
  80. package/dist/plugins/duckdb.d.ts.map +1 -0
  81. package/dist/plugins/duckdb.js +170 -0
  82. package/dist/plugins/duckdb.js.map +1 -0
  83. package/dist/plugins/groq.cjs +97 -0
  84. package/dist/plugins/groq.cjs.map +1 -0
  85. package/dist/plugins/groq.d.ts +13 -0
  86. package/dist/plugins/groq.d.ts.map +1 -0
  87. package/dist/plugins/groq.js +97 -0
  88. package/dist/plugins/groq.js.map +1 -0
  89. package/dist/plugins/index.d.ts +10 -0
  90. package/dist/plugins/index.d.ts.map +1 -0
  91. package/dist/plugins/rest.cjs +92 -0
  92. package/dist/plugins/rest.cjs.map +1 -0
  93. package/dist/plugins/rest.d.ts +13 -0
  94. package/dist/plugins/rest.d.ts.map +1 -0
  95. package/dist/plugins/rest.js +92 -0
  96. package/dist/plugins/rest.js.map +1 -0
  97. package/dist/plugins/supabase.cjs +79 -0
  98. package/dist/plugins/supabase.cjs.map +1 -0
  99. package/dist/plugins/supabase.d.ts +13 -0
  100. package/dist/plugins/supabase.d.ts.map +1 -0
  101. package/dist/plugins/supabase.js +79 -0
  102. package/dist/plugins/supabase.js.map +1 -0
  103. package/dist/services/validation.cjs +40 -1
  104. package/dist/services/validation.cjs.map +1 -1
  105. package/dist/services/validation.d.ts.map +1 -1
  106. package/dist/services/validation.js +40 -1
  107. package/dist/services/validation.js.map +1 -1
  108. package/dist/types/index.d.ts +430 -0
  109. package/dist/types/index.d.ts.map +1 -1
  110. package/dist/types.d.cts +430 -0
  111. package/dist/types.d.ts +430 -0
  112. package/package.json +16 -1
  113. package/src/components/AutocompleteDropdown.tsx +329 -0
  114. package/src/components/AutocompleteFormField.tsx +288 -0
  115. package/src/components/DraggableGridItem.tsx +274 -0
  116. package/src/components/EditableUIResourceRenderer.tsx +273 -0
  117. package/src/components/GhostText.tsx +262 -0
  118. package/src/components/ResizeHandle.tsx +262 -0
  119. package/src/context/AutocompleteContext.tsx +317 -0
  120. package/src/hooks/index.ts +23 -0
  121. package/src/hooks/useAutocomplete.test.ts +334 -0
  122. package/src/hooks/useAutocomplete.ts +466 -0
  123. package/src/hooks/useDragDrop.test.ts +355 -0
  124. package/src/hooks/useDragDrop.ts +379 -0
  125. package/src/hooks/useResize.test.ts +313 -0
  126. package/src/hooks/useResize.ts +372 -0
  127. package/src/index.ts +71 -0
  128. package/src/plugins/duckdb.ts +269 -0
  129. package/src/plugins/groq.ts +137 -0
  130. package/src/plugins/index.ts +14 -0
  131. package/src/plugins/rest.ts +147 -0
  132. package/src/plugins/supabase.ts +120 -0
  133. package/src/services/validation.ts +46 -0
  134. package/src/styles/autocomplete.css +356 -0
  135. package/src/styles/drag-drop.css +297 -0
  136. package/src/styles/index.css +7 -0
  137. package/src/types/index.ts +529 -0
  138. package/src/vite-env.d.ts +18 -0
  139. package/tsconfig.tsbuildinfo +1 -1
  140. package/vite.config.ts +2 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * ResizeHandle Component
3
+ * Visual handle for resizing grid components
4
+ *
5
+ * Sprint Drag-Drop Feature
6
+ */
7
+ import { Component } from 'solid-js';
8
+ /**
9
+ * Resize edge types
10
+ */
11
+ export type ResizeEdge = 'left' | 'right' | 'top' | 'bottom';
12
+ /**
13
+ * Props for ResizeHandle
14
+ */
15
+ export interface ResizeHandleProps {
16
+ /**
17
+ * Which edge this handle is on
18
+ */
19
+ edge: ResizeEdge;
20
+ /**
21
+ * Callback when resize starts
22
+ */
23
+ onResizeStart?: (edge: ResizeEdge) => void;
24
+ /**
25
+ * Whether the handle is disabled
26
+ */
27
+ disabled?: boolean;
28
+ /**
29
+ * Whether resize is active
30
+ */
31
+ isActive?: boolean;
32
+ /**
33
+ * Custom class
34
+ */
35
+ class?: string;
36
+ /**
37
+ * Handle size in pixels
38
+ */
39
+ size?: number;
40
+ /**
41
+ * Hit area size in pixels (larger than visible size for easier grabbing)
42
+ */
43
+ hitAreaSize?: number;
44
+ }
45
+ /**
46
+ * ResizeHandle Component
47
+ */
48
+ export declare const ResizeHandle: Component<ResizeHandleProps>;
49
+ export default ResizeHandle;
50
+ //# sourceMappingURL=ResizeHandle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResizeHandle.d.ts","sourceRoot":"","sources":["../../src/components/ResizeHandle.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAA+B,MAAM,UAAU,CAAA;AAEjE;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,QAAQ,CAAA;AAE5D;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC;;OAEG;IACH,IAAI,EAAE,UAAU,CAAA;IAEhB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IAE1C;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAElB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IAEd;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IAEb;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AA6HD;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,SAAS,CAAC,iBAAiB,CA+ErD,CAAA;AAED,eAAe,YAAY,CAAA"}
@@ -0,0 +1,173 @@
1
+ import { delegateEvents, getNextElement, template, setAttribute, effect, className, style, runHydrationEvents } from "solid-js/web";
2
+ import { mergeProps, createMemo } from "solid-js";
3
+ var _tmpl$ = /* @__PURE__ */ template(`<div role=separator><div class=mcp-resize-indicator>`);
4
+ function getCursor(edge) {
5
+ switch (edge) {
6
+ case "left":
7
+ case "right":
8
+ return "ew-resize";
9
+ case "top":
10
+ case "bottom":
11
+ return "ns-resize";
12
+ default:
13
+ return "default";
14
+ }
15
+ }
16
+ function getPositionStyle(edge, hitAreaSize) {
17
+ const halfSize = hitAreaSize / 2;
18
+ switch (edge) {
19
+ case "left":
20
+ return {
21
+ left: `-${halfSize}px`,
22
+ top: "0",
23
+ width: `${hitAreaSize}px`,
24
+ height: "100%"
25
+ };
26
+ case "right":
27
+ return {
28
+ right: `-${halfSize}px`,
29
+ top: "0",
30
+ width: `${hitAreaSize}px`,
31
+ height: "100%"
32
+ };
33
+ case "top":
34
+ return {
35
+ top: `-${halfSize}px`,
36
+ left: "0",
37
+ width: "100%",
38
+ height: `${hitAreaSize}px`
39
+ };
40
+ case "bottom":
41
+ return {
42
+ bottom: `-${halfSize}px`,
43
+ left: "0",
44
+ width: "100%",
45
+ height: `${hitAreaSize}px`
46
+ };
47
+ default:
48
+ return {};
49
+ }
50
+ }
51
+ function getIndicatorStyle(edge, size, isActive) {
52
+ const baseColor = isActive ? "#3b82f6" : "#9ca3af";
53
+ const common = {
54
+ position: "absolute",
55
+ "background-color": baseColor,
56
+ "border-radius": `${size / 2}px`,
57
+ transition: "background-color 150ms ease, opacity 150ms ease",
58
+ opacity: isActive ? "1" : "0"
59
+ };
60
+ switch (edge) {
61
+ case "left":
62
+ return {
63
+ ...common,
64
+ left: "50%",
65
+ top: "50%",
66
+ transform: "translate(-50%, -50%)",
67
+ width: `${size}px`,
68
+ height: "40px",
69
+ "max-height": "60%"
70
+ };
71
+ case "right":
72
+ return {
73
+ ...common,
74
+ right: "50%",
75
+ top: "50%",
76
+ transform: "translate(50%, -50%)",
77
+ width: `${size}px`,
78
+ height: "40px",
79
+ "max-height": "60%"
80
+ };
81
+ case "top":
82
+ return {
83
+ ...common,
84
+ top: "50%",
85
+ left: "50%",
86
+ transform: "translate(-50%, -50%)",
87
+ width: "40px",
88
+ "max-width": "60%",
89
+ height: `${size}px`
90
+ };
91
+ case "bottom":
92
+ return {
93
+ ...common,
94
+ bottom: "50%",
95
+ left: "50%",
96
+ transform: "translate(-50%, 50%)",
97
+ width: "40px",
98
+ "max-width": "60%",
99
+ height: `${size}px`
100
+ };
101
+ default:
102
+ return common;
103
+ }
104
+ }
105
+ const ResizeHandle = (props) => {
106
+ const merged = mergeProps({
107
+ disabled: false,
108
+ isActive: false,
109
+ size: 4,
110
+ hitAreaSize: 12
111
+ }, props);
112
+ const handlePointerDown = (e) => {
113
+ var _a;
114
+ if (merged.disabled) return;
115
+ e.preventDefault();
116
+ e.stopPropagation();
117
+ (_a = props.onResizeStart) == null ? void 0 : _a.call(props, props.edge);
118
+ };
119
+ const containerStyle = createMemo(() => ({
120
+ position: "absolute",
121
+ "z-index": "10",
122
+ cursor: merged.disabled ? "default" : getCursor(props.edge),
123
+ "user-select": "none",
124
+ "touch-action": "none",
125
+ ...getPositionStyle(props.edge, merged.hitAreaSize)
126
+ }));
127
+ const indicatorStyle = createMemo(() => getIndicatorStyle(props.edge, merged.size, merged.isActive));
128
+ const classNames = createMemo(() => {
129
+ const classes = ["mcp-resize-handle", `mcp-resize-handle-${props.edge}`];
130
+ if (merged.disabled) classes.push("mcp-resize-handle-disabled");
131
+ if (merged.isActive) classes.push("mcp-resize-handle-active");
132
+ if (props.class) classes.push(props.class);
133
+ return classes.join(" ");
134
+ });
135
+ return (() => {
136
+ var _el$ = getNextElement(_tmpl$), _el$2 = _el$.firstChild;
137
+ _el$.$$keydown = (e) => {
138
+ var _a;
139
+ if (merged.disabled) return;
140
+ if (e.key === "Enter" || e.key === " ") {
141
+ e.preventDefault();
142
+ (_a = props.onResizeStart) == null ? void 0 : _a.call(props, props.edge);
143
+ }
144
+ };
145
+ _el$.$$pointerdown = handlePointerDown;
146
+ setAttribute(_el$, "aria-valuenow", void 0);
147
+ effect((_p$) => {
148
+ var _v$ = classNames(), _v$2 = containerStyle(), _v$3 = props.edge, _v$4 = props.edge === "left" || props.edge === "right" ? "vertical" : "horizontal", _v$5 = merged.disabled ? -1 : 0, _v$6 = indicatorStyle();
149
+ _v$ !== _p$.e && className(_el$, _p$.e = _v$);
150
+ _p$.t = style(_el$, _v$2, _p$.t);
151
+ _v$3 !== _p$.a && setAttribute(_el$, "data-resize-edge", _p$.a = _v$3);
152
+ _v$4 !== _p$.o && setAttribute(_el$, "aria-orientation", _p$.o = _v$4);
153
+ _v$5 !== _p$.i && setAttribute(_el$, "tabindex", _p$.i = _v$5);
154
+ _p$.n = style(_el$2, _v$6, _p$.n);
155
+ return _p$;
156
+ }, {
157
+ e: void 0,
158
+ t: void 0,
159
+ a: void 0,
160
+ o: void 0,
161
+ i: void 0,
162
+ n: void 0
163
+ });
164
+ runHydrationEvents();
165
+ return _el$;
166
+ })();
167
+ };
168
+ delegateEvents(["pointerdown", "keydown"]);
169
+ export {
170
+ ResizeHandle,
171
+ ResizeHandle as default
172
+ };
173
+ //# sourceMappingURL=ResizeHandle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResizeHandle.js","sources":["../../src/components/ResizeHandle.tsx"],"sourcesContent":["/**\n * ResizeHandle Component\n * Visual handle for resizing grid components\n *\n * Sprint Drag-Drop Feature\n */\n\nimport { Component, JSX, createMemo, mergeProps } from 'solid-js'\n\n/**\n * Resize edge types\n */\nexport type ResizeEdge = 'left' | 'right' | 'top' | 'bottom'\n\n/**\n * Props for ResizeHandle\n */\nexport interface ResizeHandleProps {\n /**\n * Which edge this handle is on\n */\n edge: ResizeEdge\n\n /**\n * Callback when resize starts\n */\n onResizeStart?: (edge: ResizeEdge) => void\n\n /**\n * Whether the handle is disabled\n */\n disabled?: boolean\n\n /**\n * Whether resize is active\n */\n isActive?: boolean\n\n /**\n * Custom class\n */\n class?: string\n\n /**\n * Handle size in pixels\n */\n size?: number\n\n /**\n * Hit area size in pixels (larger than visible size for easier grabbing)\n */\n hitAreaSize?: number\n}\n\n/**\n * Get cursor style for edge\n */\nfunction getCursor(edge: ResizeEdge): string {\n switch (edge) {\n case 'left':\n case 'right':\n return 'ew-resize'\n case 'top':\n case 'bottom':\n return 'ns-resize'\n default:\n return 'default'\n }\n}\n\n/**\n * Get position styles for edge\n */\nfunction getPositionStyle(\n edge: ResizeEdge,\n hitAreaSize: number\n): JSX.CSSProperties {\n const halfSize = hitAreaSize / 2\n\n switch (edge) {\n case 'left':\n return {\n left: `-${halfSize}px`,\n top: '0',\n width: `${hitAreaSize}px`,\n height: '100%'\n }\n case 'right':\n return {\n right: `-${halfSize}px`,\n top: '0',\n width: `${hitAreaSize}px`,\n height: '100%'\n }\n case 'top':\n return {\n top: `-${halfSize}px`,\n left: '0',\n width: '100%',\n height: `${hitAreaSize}px`\n }\n case 'bottom':\n return {\n bottom: `-${halfSize}px`,\n left: '0',\n width: '100%',\n height: `${hitAreaSize}px`\n }\n default:\n return {}\n }\n}\n\n/**\n * Get visual indicator styles for edge\n */\nfunction getIndicatorStyle(\n edge: ResizeEdge,\n size: number,\n isActive: boolean\n): JSX.CSSProperties {\n const baseColor = isActive ? '#3b82f6' : '#9ca3af'\n\n const common: JSX.CSSProperties = {\n position: 'absolute',\n 'background-color': baseColor,\n 'border-radius': `${size / 2}px`,\n transition: 'background-color 150ms ease, opacity 150ms ease',\n opacity: isActive ? '1' : '0'\n }\n\n switch (edge) {\n case 'left':\n return {\n ...common,\n left: '50%',\n top: '50%',\n transform: 'translate(-50%, -50%)',\n width: `${size}px`,\n height: '40px',\n 'max-height': '60%'\n }\n case 'right':\n return {\n ...common,\n right: '50%',\n top: '50%',\n transform: 'translate(50%, -50%)',\n width: `${size}px`,\n height: '40px',\n 'max-height': '60%'\n }\n case 'top':\n return {\n ...common,\n top: '50%',\n left: '50%',\n transform: 'translate(-50%, -50%)',\n width: '40px',\n 'max-width': '60%',\n height: `${size}px`\n }\n case 'bottom':\n return {\n ...common,\n bottom: '50%',\n left: '50%',\n transform: 'translate(-50%, 50%)',\n width: '40px',\n 'max-width': '60%',\n height: `${size}px`\n }\n default:\n return common\n }\n}\n\n/**\n * ResizeHandle Component\n */\nexport const ResizeHandle: Component<ResizeHandleProps> = (props) => {\n const merged = mergeProps(\n {\n disabled: false,\n isActive: false,\n size: 4,\n hitAreaSize: 12\n },\n props\n )\n\n const handlePointerDown = (e: PointerEvent) => {\n if (merged.disabled) return\n\n e.preventDefault()\n e.stopPropagation()\n\n props.onResizeStart?.(props.edge)\n }\n\n // Container styles\n const containerStyle = createMemo((): JSX.CSSProperties => ({\n position: 'absolute',\n 'z-index': '10',\n cursor: merged.disabled ? 'default' : getCursor(props.edge),\n 'user-select': 'none',\n 'touch-action': 'none',\n ...getPositionStyle(props.edge, merged.hitAreaSize)\n }))\n\n // Indicator styles\n const indicatorStyle = createMemo(() =>\n getIndicatorStyle(props.edge, merged.size, merged.isActive)\n )\n\n // Class names\n const classNames = createMemo(() => {\n const classes = [\n 'mcp-resize-handle',\n `mcp-resize-handle-${props.edge}`\n ]\n\n if (merged.disabled) classes.push('mcp-resize-handle-disabled')\n if (merged.isActive) classes.push('mcp-resize-handle-active')\n if (props.class) classes.push(props.class)\n\n return classes.join(' ')\n })\n\n return (\n <div\n class={classNames()}\n style={containerStyle()}\n onPointerDown={handlePointerDown}\n data-resize-edge={props.edge}\n role=\"separator\"\n aria-orientation={\n props.edge === 'left' || props.edge === 'right'\n ? 'vertical'\n : 'horizontal'\n }\n aria-valuenow={undefined}\n tabIndex={merged.disabled ? -1 : 0}\n onKeyDown={(e) => {\n // Allow keyboard resizing\n if (merged.disabled) return\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault()\n props.onResizeStart?.(props.edge)\n }\n }}\n >\n {/* Visual indicator */}\n <div\n class=\"mcp-resize-indicator\"\n style={indicatorStyle()}\n />\n </div>\n )\n}\n\nexport default ResizeHandle\n"],"names":["getCursor","edge","getPositionStyle","hitAreaSize","halfSize","left","top","width","height","right","bottom","getIndicatorStyle","size","isActive","baseColor","common","position","transition","opacity","transform","ResizeHandle","props","merged","mergeProps","disabled","handlePointerDown","e","preventDefault","stopPropagation","onResizeStart","containerStyle","createMemo","cursor","indicatorStyle","classNames","classes","push","class","join","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","$$keydown","key","$$pointerdown","_$setAttribute","undefined","_$effect","_p$","_v$","_v$2","_v$3","_v$4","_v$5","_v$6","_$className","t","_$style","a","o","i","n","_$runHydrationEvents","_$delegateEvents"],"mappings":"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"}
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const web = require("solid-js/web");
4
+ const solidJs = require("solid-js");
5
+ const AutocompleteCtx = solidJs.createContext();
6
+ function getCacheKey(input, pluginId, context) {
7
+ const contextKey = context ? JSON.stringify(context) : "";
8
+ return `${pluginId}:${input}:${contextKey}`;
9
+ }
10
+ const AutocompleteProvider = (props) => {
11
+ const [plugins, setPlugins] = solidJs.createSignal(props.plugins || []);
12
+ const [cache, setCache] = solidJs.createSignal(/* @__PURE__ */ new Map());
13
+ const config = solidJs.createMemo(() => ({
14
+ debounceMs: props.debounceMs ?? 150,
15
+ minChars: props.minChars ?? 1,
16
+ cacheTtl: props.cacheTtl ?? 6e4,
17
+ cacheEnabled: props.cacheEnabled ?? true
18
+ }));
19
+ const defaultPluginId = solidJs.createMemo(() => {
20
+ if (props.defaultPlugin) return props.defaultPlugin;
21
+ const firstPlugin = plugins()[0];
22
+ return firstPlugin == null ? void 0 : firstPlugin.id;
23
+ });
24
+ const getPlugin = (pluginId) => {
25
+ return plugins().find((p) => p.id === pluginId);
26
+ };
27
+ const isPluginReady = (pluginId) => {
28
+ const plugin = getPlugin(pluginId);
29
+ if (!plugin) return false;
30
+ if (plugin.isReady) return plugin.isReady();
31
+ return true;
32
+ };
33
+ const getFromCache = (key) => {
34
+ if (!config().cacheEnabled) return null;
35
+ const entry = cache().get(key);
36
+ if (!entry) return null;
37
+ const age = Date.now() - entry.timestamp;
38
+ if (age > config().cacheTtl) {
39
+ setCache((prev) => {
40
+ const next = new Map(prev);
41
+ next.delete(key);
42
+ return next;
43
+ });
44
+ return null;
45
+ }
46
+ return {
47
+ ...entry.result,
48
+ cached: true
49
+ };
50
+ };
51
+ const addToCache = (key, result) => {
52
+ if (!config().cacheEnabled) return;
53
+ setCache((prev) => {
54
+ const next = new Map(prev);
55
+ next.set(key, {
56
+ result,
57
+ timestamp: Date.now()
58
+ });
59
+ return next;
60
+ });
61
+ };
62
+ const getSuggestions = async (input, pluginId, context) => {
63
+ const targetPluginId = pluginId || defaultPluginId();
64
+ if (!targetPluginId) {
65
+ return {
66
+ type: "options",
67
+ options: [],
68
+ pluginId: void 0
69
+ };
70
+ }
71
+ const plugin = getPlugin(targetPluginId);
72
+ if (!plugin) {
73
+ console.warn(`[Autocomplete] Plugin not found: ${targetPluginId}`);
74
+ return {
75
+ type: "options",
76
+ options: [],
77
+ pluginId: targetPluginId
78
+ };
79
+ }
80
+ const cacheKey = getCacheKey(input, targetPluginId, context);
81
+ const cached = getFromCache(cacheKey);
82
+ if (cached) {
83
+ return cached;
84
+ }
85
+ try {
86
+ const result = await plugin.getSuggestions(input, context);
87
+ result.pluginId = targetPluginId;
88
+ addToCache(cacheKey, result);
89
+ return result;
90
+ } catch (error) {
91
+ console.error(`[Autocomplete] Plugin error (${targetPluginId}):`, error);
92
+ return {
93
+ type: "options",
94
+ options: [],
95
+ pluginId: targetPluginId
96
+ };
97
+ }
98
+ };
99
+ const registerPlugin = (plugin) => {
100
+ setPlugins((prev) => {
101
+ const filtered = prev.filter((p) => p.id !== plugin.id);
102
+ return [...filtered, plugin];
103
+ });
104
+ };
105
+ const unregisterPlugin = (pluginId) => {
106
+ const plugin = getPlugin(pluginId);
107
+ if (plugin == null ? void 0 : plugin.dispose) {
108
+ plugin.dispose();
109
+ }
110
+ setPlugins((prev) => prev.filter((p) => p.id !== pluginId));
111
+ };
112
+ const clearCache = () => {
113
+ setCache(/* @__PURE__ */ new Map());
114
+ };
115
+ solidJs.onCleanup(() => {
116
+ plugins().forEach((plugin) => {
117
+ if (plugin.dispose) {
118
+ try {
119
+ plugin.dispose();
120
+ } catch (e) {
121
+ console.error(`[Autocomplete] Error disposing plugin ${plugin.id}:`, e);
122
+ }
123
+ }
124
+ });
125
+ });
126
+ const contextValue = {
127
+ getSuggestions,
128
+ plugins,
129
+ defaultPluginId,
130
+ isPluginReady,
131
+ getPlugin,
132
+ registerPlugin,
133
+ unregisterPlugin,
134
+ clearCache,
135
+ config: config()
136
+ };
137
+ return web.createComponent(AutocompleteCtx.Provider, {
138
+ value: contextValue,
139
+ get children() {
140
+ return props.children;
141
+ }
142
+ });
143
+ };
144
+ function useAutocompleteContext() {
145
+ const context = solidJs.useContext(AutocompleteCtx);
146
+ if (!context) {
147
+ throw new Error("useAutocompleteContext must be used within an AutocompleteProvider");
148
+ }
149
+ return context;
150
+ }
151
+ function useAutocompleteContextSafe() {
152
+ return solidJs.useContext(AutocompleteCtx);
153
+ }
154
+ exports.AutocompleteCtx = AutocompleteCtx;
155
+ exports.AutocompleteProvider = AutocompleteProvider;
156
+ exports.useAutocompleteContext = useAutocompleteContext;
157
+ exports.useAutocompleteContextSafe = useAutocompleteContextSafe;
158
+ //# sourceMappingURL=AutocompleteContext.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompleteContext.cjs","sources":["../../src/context/AutocompleteContext.tsx"],"sourcesContent":["/**\n * AutocompleteContext - Context provider for autocomplete functionality\n * Manages plugins and provides unified autocomplete API\n *\n * Sprint Autocomplete Feature\n */\n\nimport {\n createContext,\n useContext,\n ParentComponent,\n Accessor,\n createSignal,\n createMemo,\n onCleanup\n} from 'solid-js'\nimport type {\n AutocompletePlugin,\n AutocompleteResult,\n AutocompleteContext as AutocompleteContextData,\n AutocompleteProviderConfig\n} from '../types'\n\n/**\n * Cache entry for autocomplete results\n */\ninterface CacheEntry {\n result: AutocompleteResult\n timestamp: number\n}\n\n/**\n * Context value interface\n */\nexport interface AutocompleteContextValue {\n /**\n * Get suggestions from a plugin\n */\n getSuggestions: (\n input: string,\n pluginId?: string,\n context?: AutocompleteContextData\n ) => Promise<AutocompleteResult>\n\n /**\n * Get registered plugins\n */\n plugins: Accessor<AutocompletePlugin[]>\n\n /**\n * Get default plugin ID\n */\n defaultPluginId: Accessor<string | undefined>\n\n /**\n * Check if a plugin is ready\n */\n isPluginReady: (pluginId: string) => boolean\n\n /**\n * Get plugin by ID\n */\n getPlugin: (pluginId: string) => AutocompletePlugin | undefined\n\n /**\n * Register a new plugin\n */\n registerPlugin: (plugin: AutocompletePlugin) => void\n\n /**\n * Unregister a plugin\n */\n unregisterPlugin: (pluginId: string) => void\n\n /**\n * Clear cache\n */\n clearCache: () => void\n\n /**\n * Global config\n */\n config: {\n debounceMs: number\n minChars: number\n cacheTtl: number\n cacheEnabled: boolean\n }\n}\n\n// Create context with undefined default\nconst AutocompleteCtx = createContext<AutocompleteContextValue>()\n\n/**\n * Props for AutocompleteProvider\n */\nexport interface AutocompleteProviderProps extends AutocompleteProviderConfig {\n children: any\n}\n\n/**\n * Generate cache key\n */\nfunction getCacheKey(input: string, pluginId: string, context?: AutocompleteContextData): string {\n const contextKey = context ? JSON.stringify(context) : ''\n return `${pluginId}:${input}:${contextKey}`\n}\n\n/**\n * AutocompleteProvider Component\n * Provides autocomplete context to child components\n */\nexport const AutocompleteProvider: ParentComponent<AutocompleteProviderProps> = (props) => {\n // Plugin registry\n const [plugins, setPlugins] = createSignal<AutocompletePlugin[]>(props.plugins || [])\n\n // Result cache\n const [cache, setCache] = createSignal<Map<string, CacheEntry>>(new Map())\n\n // Config with defaults\n const config = createMemo(() => ({\n debounceMs: props.debounceMs ?? 150,\n minChars: props.minChars ?? 1,\n cacheTtl: props.cacheTtl ?? 60000,\n cacheEnabled: props.cacheEnabled ?? true\n }))\n\n // Default plugin ID\n const defaultPluginId = createMemo(() => {\n if (props.defaultPlugin) return props.defaultPlugin\n const firstPlugin = plugins()[0]\n return firstPlugin?.id\n })\n\n /**\n * Get plugin by ID\n */\n const getPlugin = (pluginId: string): AutocompletePlugin | undefined => {\n return plugins().find(p => p.id === pluginId)\n }\n\n /**\n * Check if plugin is ready\n */\n const isPluginReady = (pluginId: string): boolean => {\n const plugin = getPlugin(pluginId)\n if (!plugin) return false\n if (plugin.isReady) return plugin.isReady()\n return true\n }\n\n /**\n * Check cache for result\n */\n const getFromCache = (key: string): AutocompleteResult | null => {\n if (!config().cacheEnabled) return null\n\n const entry = cache().get(key)\n if (!entry) return null\n\n const age = Date.now() - entry.timestamp\n if (age > config().cacheTtl) {\n // Expired, remove from cache\n setCache(prev => {\n const next = new Map(prev)\n next.delete(key)\n return next\n })\n return null\n }\n\n return { ...entry.result, cached: true }\n }\n\n /**\n * Add result to cache\n */\n const addToCache = (key: string, result: AutocompleteResult): void => {\n if (!config().cacheEnabled) return\n\n setCache(prev => {\n const next = new Map(prev)\n next.set(key, { result, timestamp: Date.now() })\n return next\n })\n }\n\n /**\n * Get suggestions from plugin\n */\n const getSuggestions = async (\n input: string,\n pluginId?: string,\n context?: AutocompleteContextData\n ): Promise<AutocompleteResult> => {\n const targetPluginId = pluginId || defaultPluginId()\n\n if (!targetPluginId) {\n return { type: 'options', options: [], pluginId: undefined }\n }\n\n const plugin = getPlugin(targetPluginId)\n if (!plugin) {\n console.warn(`[Autocomplete] Plugin not found: ${targetPluginId}`)\n return { type: 'options', options: [], pluginId: targetPluginId }\n }\n\n // Check cache\n const cacheKey = getCacheKey(input, targetPluginId, context)\n const cached = getFromCache(cacheKey)\n if (cached) {\n return cached\n }\n\n try {\n const result = await plugin.getSuggestions(input, context)\n result.pluginId = targetPluginId\n\n // Cache result\n addToCache(cacheKey, result)\n\n return result\n } catch (error) {\n console.error(`[Autocomplete] Plugin error (${targetPluginId}):`, error)\n return {\n type: 'options',\n options: [],\n pluginId: targetPluginId\n }\n }\n }\n\n /**\n * Register a new plugin\n */\n const registerPlugin = (plugin: AutocompletePlugin): void => {\n setPlugins(prev => {\n // Remove existing plugin with same ID\n const filtered = prev.filter(p => p.id !== plugin.id)\n return [...filtered, plugin]\n })\n }\n\n /**\n * Unregister a plugin\n */\n const unregisterPlugin = (pluginId: string): void => {\n const plugin = getPlugin(pluginId)\n if (plugin?.dispose) {\n plugin.dispose()\n }\n setPlugins(prev => prev.filter(p => p.id !== pluginId))\n }\n\n /**\n * Clear cache\n */\n const clearCache = (): void => {\n setCache(new Map())\n }\n\n // Cleanup on unmount\n onCleanup(() => {\n // Dispose all plugins\n plugins().forEach(plugin => {\n if (plugin.dispose) {\n try {\n plugin.dispose()\n } catch (e) {\n console.error(`[Autocomplete] Error disposing plugin ${plugin.id}:`, e)\n }\n }\n })\n })\n\n // Context value\n const contextValue: AutocompleteContextValue = {\n getSuggestions,\n plugins,\n defaultPluginId,\n isPluginReady,\n getPlugin,\n registerPlugin,\n unregisterPlugin,\n clearCache,\n config: config()\n }\n\n return (\n <AutocompleteCtx.Provider value={contextValue}>\n {props.children}\n </AutocompleteCtx.Provider>\n )\n}\n\n/**\n * Hook to use autocomplete context\n * @throws Error if used outside provider\n */\nexport function useAutocompleteContext(): AutocompleteContextValue {\n const context = useContext(AutocompleteCtx)\n if (!context) {\n throw new Error(\n 'useAutocompleteContext must be used within an AutocompleteProvider'\n )\n }\n return context\n}\n\n/**\n * Safe hook that returns undefined if outside provider\n */\nexport function useAutocompleteContextSafe(): AutocompleteContextValue | undefined {\n return useContext(AutocompleteCtx)\n}\n\nexport { AutocompleteCtx }\n"],"names":["AutocompleteCtx","createContext","getCacheKey","input","pluginId","context","contextKey","JSON","stringify","AutocompleteProvider","props","plugins","setPlugins","createSignal","cache","setCache","Map","config","createMemo","debounceMs","minChars","cacheTtl","cacheEnabled","defaultPluginId","defaultPlugin","firstPlugin","id","getPlugin","find","p","isPluginReady","plugin","isReady","getFromCache","key","entry","get","age","Date","now","timestamp","prev","next","delete","result","cached","addToCache","set","getSuggestions","targetPluginId","type","options","undefined","console","warn","cacheKey","error","registerPlugin","filtered","filter","unregisterPlugin","dispose","clearCache","onCleanup","forEach","e","contextValue","_$createComponent","Provider","value","children","useAutocompleteContext","useContext","Error","useAutocompleteContextSafe"],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * AutocompleteContext - Context provider for autocomplete functionality
3
+ * Manages plugins and provides unified autocomplete API
4
+ *
5
+ * Sprint Autocomplete Feature
6
+ */
7
+ import { ParentComponent, Accessor } from 'solid-js';
8
+ import type { AutocompletePlugin, AutocompleteResult, AutocompleteContext as AutocompleteContextData, AutocompleteProviderConfig } from '../types';
9
+ /**
10
+ * Context value interface
11
+ */
12
+ export interface AutocompleteContextValue {
13
+ /**
14
+ * Get suggestions from a plugin
15
+ */
16
+ getSuggestions: (input: string, pluginId?: string, context?: AutocompleteContextData) => Promise<AutocompleteResult>;
17
+ /**
18
+ * Get registered plugins
19
+ */
20
+ plugins: Accessor<AutocompletePlugin[]>;
21
+ /**
22
+ * Get default plugin ID
23
+ */
24
+ defaultPluginId: Accessor<string | undefined>;
25
+ /**
26
+ * Check if a plugin is ready
27
+ */
28
+ isPluginReady: (pluginId: string) => boolean;
29
+ /**
30
+ * Get plugin by ID
31
+ */
32
+ getPlugin: (pluginId: string) => AutocompletePlugin | undefined;
33
+ /**
34
+ * Register a new plugin
35
+ */
36
+ registerPlugin: (plugin: AutocompletePlugin) => void;
37
+ /**
38
+ * Unregister a plugin
39
+ */
40
+ unregisterPlugin: (pluginId: string) => void;
41
+ /**
42
+ * Clear cache
43
+ */
44
+ clearCache: () => void;
45
+ /**
46
+ * Global config
47
+ */
48
+ config: {
49
+ debounceMs: number;
50
+ minChars: number;
51
+ cacheTtl: number;
52
+ cacheEnabled: boolean;
53
+ };
54
+ }
55
+ declare const AutocompleteCtx: import("solid-js").Context<AutocompleteContextValue | undefined>;
56
+ /**
57
+ * Props for AutocompleteProvider
58
+ */
59
+ export interface AutocompleteProviderProps extends AutocompleteProviderConfig {
60
+ children: any;
61
+ }
62
+ /**
63
+ * AutocompleteProvider Component
64
+ * Provides autocomplete context to child components
65
+ */
66
+ export declare const AutocompleteProvider: ParentComponent<AutocompleteProviderProps>;
67
+ /**
68
+ * Hook to use autocomplete context
69
+ * @throws Error if used outside provider
70
+ */
71
+ export declare function useAutocompleteContext(): AutocompleteContextValue;
72
+ /**
73
+ * Safe hook that returns undefined if outside provider
74
+ */
75
+ export declare function useAutocompleteContextSafe(): AutocompleteContextValue | undefined;
76
+ export { AutocompleteCtx };
77
+ //# sourceMappingURL=AutocompleteContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AutocompleteContext.d.ts","sourceRoot":"","sources":["../../src/context/AutocompleteContext.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,eAAe,EACf,QAAQ,EAIT,MAAM,UAAU,CAAA;AACjB,OAAO,KAAK,EACV,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,IAAI,uBAAuB,EAC9C,0BAA0B,EAC3B,MAAM,UAAU,CAAA;AAUjB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,cAAc,EAAE,CACd,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,uBAAuB,KAC9B,OAAO,CAAC,kBAAkB,CAAC,CAAA;IAEhC;;OAEG;IACH,OAAO,EAAE,QAAQ,CAAC,kBAAkB,EAAE,CAAC,CAAA;IAEvC;;OAEG;IACH,eAAe,EAAE,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;IAE7C;;OAEG;IACH,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IAE5C;;OAEG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAA;IAE/D;;OAEG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,CAAA;IAEpD;;OAEG;IACH,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAE5C;;OAEG;IACH,UAAU,EAAE,MAAM,IAAI,CAAA;IAEtB;;OAEG;IACH,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAA;QAClB,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,YAAY,EAAE,OAAO,CAAA;KACtB,CAAA;CACF;AAGD,QAAA,MAAM,eAAe,kEAA4C,CAAA;AAEjE;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,0BAA0B;IAC3E,QAAQ,EAAE,GAAG,CAAA;CACd;AAUD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,eAAe,CAAC,yBAAyB,CAqL3E,CAAA;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,wBAAwB,CAQjE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,wBAAwB,GAAG,SAAS,CAEjF;AAED,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -0,0 +1,158 @@
1
+ import { createComponent } from "solid-js/web";
2
+ import { createContext, createSignal, createMemo, onCleanup, useContext } from "solid-js";
3
+ const AutocompleteCtx = createContext();
4
+ function getCacheKey(input, pluginId, context) {
5
+ const contextKey = context ? JSON.stringify(context) : "";
6
+ return `${pluginId}:${input}:${contextKey}`;
7
+ }
8
+ const AutocompleteProvider = (props) => {
9
+ const [plugins, setPlugins] = createSignal(props.plugins || []);
10
+ const [cache, setCache] = createSignal(/* @__PURE__ */ new Map());
11
+ const config = createMemo(() => ({
12
+ debounceMs: props.debounceMs ?? 150,
13
+ minChars: props.minChars ?? 1,
14
+ cacheTtl: props.cacheTtl ?? 6e4,
15
+ cacheEnabled: props.cacheEnabled ?? true
16
+ }));
17
+ const defaultPluginId = createMemo(() => {
18
+ if (props.defaultPlugin) return props.defaultPlugin;
19
+ const firstPlugin = plugins()[0];
20
+ return firstPlugin == null ? void 0 : firstPlugin.id;
21
+ });
22
+ const getPlugin = (pluginId) => {
23
+ return plugins().find((p) => p.id === pluginId);
24
+ };
25
+ const isPluginReady = (pluginId) => {
26
+ const plugin = getPlugin(pluginId);
27
+ if (!plugin) return false;
28
+ if (plugin.isReady) return plugin.isReady();
29
+ return true;
30
+ };
31
+ const getFromCache = (key) => {
32
+ if (!config().cacheEnabled) return null;
33
+ const entry = cache().get(key);
34
+ if (!entry) return null;
35
+ const age = Date.now() - entry.timestamp;
36
+ if (age > config().cacheTtl) {
37
+ setCache((prev) => {
38
+ const next = new Map(prev);
39
+ next.delete(key);
40
+ return next;
41
+ });
42
+ return null;
43
+ }
44
+ return {
45
+ ...entry.result,
46
+ cached: true
47
+ };
48
+ };
49
+ const addToCache = (key, result) => {
50
+ if (!config().cacheEnabled) return;
51
+ setCache((prev) => {
52
+ const next = new Map(prev);
53
+ next.set(key, {
54
+ result,
55
+ timestamp: Date.now()
56
+ });
57
+ return next;
58
+ });
59
+ };
60
+ const getSuggestions = async (input, pluginId, context) => {
61
+ const targetPluginId = pluginId || defaultPluginId();
62
+ if (!targetPluginId) {
63
+ return {
64
+ type: "options",
65
+ options: [],
66
+ pluginId: void 0
67
+ };
68
+ }
69
+ const plugin = getPlugin(targetPluginId);
70
+ if (!plugin) {
71
+ console.warn(`[Autocomplete] Plugin not found: ${targetPluginId}`);
72
+ return {
73
+ type: "options",
74
+ options: [],
75
+ pluginId: targetPluginId
76
+ };
77
+ }
78
+ const cacheKey = getCacheKey(input, targetPluginId, context);
79
+ const cached = getFromCache(cacheKey);
80
+ if (cached) {
81
+ return cached;
82
+ }
83
+ try {
84
+ const result = await plugin.getSuggestions(input, context);
85
+ result.pluginId = targetPluginId;
86
+ addToCache(cacheKey, result);
87
+ return result;
88
+ } catch (error) {
89
+ console.error(`[Autocomplete] Plugin error (${targetPluginId}):`, error);
90
+ return {
91
+ type: "options",
92
+ options: [],
93
+ pluginId: targetPluginId
94
+ };
95
+ }
96
+ };
97
+ const registerPlugin = (plugin) => {
98
+ setPlugins((prev) => {
99
+ const filtered = prev.filter((p) => p.id !== plugin.id);
100
+ return [...filtered, plugin];
101
+ });
102
+ };
103
+ const unregisterPlugin = (pluginId) => {
104
+ const plugin = getPlugin(pluginId);
105
+ if (plugin == null ? void 0 : plugin.dispose) {
106
+ plugin.dispose();
107
+ }
108
+ setPlugins((prev) => prev.filter((p) => p.id !== pluginId));
109
+ };
110
+ const clearCache = () => {
111
+ setCache(/* @__PURE__ */ new Map());
112
+ };
113
+ onCleanup(() => {
114
+ plugins().forEach((plugin) => {
115
+ if (plugin.dispose) {
116
+ try {
117
+ plugin.dispose();
118
+ } catch (e) {
119
+ console.error(`[Autocomplete] Error disposing plugin ${plugin.id}:`, e);
120
+ }
121
+ }
122
+ });
123
+ });
124
+ const contextValue = {
125
+ getSuggestions,
126
+ plugins,
127
+ defaultPluginId,
128
+ isPluginReady,
129
+ getPlugin,
130
+ registerPlugin,
131
+ unregisterPlugin,
132
+ clearCache,
133
+ config: config()
134
+ };
135
+ return createComponent(AutocompleteCtx.Provider, {
136
+ value: contextValue,
137
+ get children() {
138
+ return props.children;
139
+ }
140
+ });
141
+ };
142
+ function useAutocompleteContext() {
143
+ const context = useContext(AutocompleteCtx);
144
+ if (!context) {
145
+ throw new Error("useAutocompleteContext must be used within an AutocompleteProvider");
146
+ }
147
+ return context;
148
+ }
149
+ function useAutocompleteContextSafe() {
150
+ return useContext(AutocompleteCtx);
151
+ }
152
+ export {
153
+ AutocompleteCtx,
154
+ AutocompleteProvider,
155
+ useAutocompleteContext,
156
+ useAutocompleteContextSafe
157
+ };
158
+ //# sourceMappingURL=AutocompleteContext.js.map