@cpreston321/reactools-sdk 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,117 @@
1
+ # @cpreston321/reactools-sdk
2
+
3
+ SDK for creating custom tabs and plugins for Reactools DevTools.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @cpreston321/reactools-sdk
9
+ ```
10
+
11
+ ## Creating Custom Tabs
12
+
13
+ ### Using `registerTab`
14
+
15
+ ```tsx
16
+ import { registerTab } from '@cpreston321/reactools-sdk';
17
+ import { Database } from 'lucide-react';
18
+
19
+ const { unregister } = registerTab({
20
+ id: 'my-custom-tab',
21
+ title: 'My Tab',
22
+ icon: Database,
23
+ category: 'app',
24
+ view: {
25
+ type: 'component',
26
+ component: MyTabContent,
27
+ },
28
+ });
29
+
30
+ // Later: unregister()
31
+ ```
32
+
33
+ ### Using the Hook
34
+
35
+ ```tsx
36
+ import { useRegisterTab } from '@cpreston321/reactools-sdk';
37
+
38
+ function MyComponent() {
39
+ useRegisterTab({
40
+ id: 'my-tab',
41
+ title: 'My Tab',
42
+ icon: 'Code',
43
+ view: {
44
+ type: 'component',
45
+ component: MyTabContent,
46
+ },
47
+ });
48
+
49
+ return <div>...</div>;
50
+ }
51
+ ```
52
+
53
+ ## Creating Plugins
54
+
55
+ ```tsx
56
+ import { createPlugin } from '@cpreston321/reactools-sdk';
57
+
58
+ const myPlugin = createPlugin({
59
+ id: 'my-plugin',
60
+ name: 'My Plugin',
61
+ version: '1.0.0',
62
+ tabs: [
63
+ {
64
+ id: 'overview',
65
+ title: 'Overview',
66
+ icon: 'LayoutDashboard',
67
+ view: { type: 'component', component: OverviewTab },
68
+ },
69
+ ],
70
+ setup: (ctx) => {
71
+ ctx.on('panel:open', () => console.log('Panel opened!'));
72
+ },
73
+ });
74
+ ```
75
+
76
+ ## API Reference
77
+
78
+ ### Types
79
+
80
+ ```typescript
81
+ interface TabDefinition {
82
+ id: string;
83
+ title: string;
84
+ icon: string | ComponentType<{ className?: string }>;
85
+ category?: 'pinned' | 'app' | 'modules' | 'custom';
86
+ order?: number;
87
+ badge?: number | string | (() => number | string | null);
88
+ show?: () => boolean;
89
+ view: TabViewType;
90
+ }
91
+
92
+ type TabViewType =
93
+ | { type: 'component'; component: ComponentType }
94
+ | { type: 'iframe'; src: string; permissions?: string[] }
95
+ | { type: 'launch'; label: string; action: () => void };
96
+ ```
97
+
98
+ ### Hooks
99
+
100
+ ```typescript
101
+ import { useDevTools, useRegisterTab } from '@cpreston321/reactools-sdk';
102
+
103
+ const { tabs, tabsByCategory, context } = useDevTools();
104
+ ```
105
+
106
+ ### Events
107
+
108
+ ```typescript
109
+ import { tabRegistry } from '@cpreston321/reactools-sdk';
110
+
111
+ tabRegistry.on('panel:open', () => {});
112
+ tabRegistry.on('panel:close', () => {});
113
+ tabRegistry.on('tab:change', ({ tabId }) => {});
114
+ tabRegistry.on('position:change', ({ position }) => {});
115
+ ```
116
+
117
+ See the [main documentation](https://github.com/your-username/reactools) for full details.
@@ -0,0 +1,41 @@
1
+ import { PluginDefinition, RegisterDefinition } from '../types';
2
+ /**
3
+ * Create and register a Reactools plugin
4
+ *
5
+ * Plugins allow you to bundle multiple tabs and setup logic together.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * import { createPlugin } from '@cpreston321/reactools-sdk';
10
+ *
11
+ * const plugin = createPlugin({
12
+ * id: 'my-plugin',
13
+ * name: 'My Plugin',
14
+ * version: '1.0.0',
15
+ * tabs: [
16
+ * {
17
+ * id: 'overview',
18
+ * title: 'Overview',
19
+ * icon: 'LayoutDashboard',
20
+ * view: { type: 'component', component: OverviewTab },
21
+ * },
22
+ * {
23
+ * id: 'settings',
24
+ * title: 'Settings',
25
+ * icon: 'Settings',
26
+ * view: { type: 'component', component: SettingsTab },
27
+ * },
28
+ * ],
29
+ * setup: (ctx) => {
30
+ * ctx.on('panel:open', () => console.log('Panel opened!'));
31
+ * },
32
+ * });
33
+ *
34
+ * // Later: plugin.unregister();
35
+ * ```
36
+ *
37
+ * @param plugin - Plugin definition object
38
+ * @returns Function to unregister the plugin and all its tabs
39
+ */
40
+ export declare function createPlugin(plugin: PluginDefinition): RegisterDefinition;
41
+ //# sourceMappingURL=createPlugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createPlugin.d.ts","sourceRoot":"","sources":["../../src/api/createPlugin.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAErE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,gBAAgB,GAAG,kBAAkB,CAEzE"}
@@ -0,0 +1,26 @@
1
+ import { RegisterDefinition, TabDefinition } from '../types';
2
+ /**
3
+ * Register a custom tab in the Reactools panel
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * import { registerTab } from '@cpreston321/reactools-sdk';
8
+ *
9
+ * const tab = registerTab({
10
+ * id: 'my-custom-tab',
11
+ * title: 'My Tab',
12
+ * icon: 'Settings',
13
+ * view: {
14
+ * type: 'component',
15
+ * component: MyTabContent,
16
+ * },
17
+ * });
18
+ *
19
+ * // Later: tab.unregister();
20
+ * ```
21
+ *
22
+ * @param tab - Tab definition object
23
+ * @returns Function to unregister the tab
24
+ */
25
+ export declare function registerTab(tab: TabDefinition): RegisterDefinition;
26
+ //# sourceMappingURL=registerTab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registerTab.d.ts","sourceRoot":"","sources":["../../src/api/registerTab.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,aAAa,GAAG,kBAAkB,CAElE"}
@@ -0,0 +1,28 @@
1
+ import { DevToolsContext, RegisterDefinition, TabDefinition } from '../types';
2
+ export interface UseDevToolsReturn {
3
+ /** All registered tabs */
4
+ tabs: TabDefinition[];
5
+ /** Tabs grouped by category */
6
+ tabsByCategory: Record<string, TabDefinition[]>;
7
+ /** Register a new tab */
8
+ registerTab: (tab: TabDefinition) => RegisterDefinition;
9
+ /** Current devtools context */
10
+ context: DevToolsContext;
11
+ }
12
+ /**
13
+ * Hook to access the devtools state and register tabs
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * function MyComponent() {
18
+ * const { tabs, context, registerTab } = useDevTools();
19
+ *
20
+ * console.log('Panel is open:', context.isOpen);
21
+ * console.log('Active tab:', context.activeTabId);
22
+ *
23
+ * return <div>...</div>;
24
+ * }
25
+ * ```
26
+ */
27
+ export declare function useDevTools(): UseDevToolsReturn;
28
+ //# sourceMappingURL=useDevTools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDevTools.d.ts","sourceRoot":"","sources":["../../src/hooks/useDevTools.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,eAAe,EACf,kBAAkB,EAClB,aAAa,EACd,MAAM,UAAU,CAAC;AAElB,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CAAC;IAChD,yBAAyB;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,kBAAkB,CAAC;IACxD,+BAA+B;IAC/B,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,IAAI,iBAAiB,CA6B/C"}
@@ -0,0 +1,22 @@
1
+ import { TabDefinition } from '../types';
2
+ /**
3
+ * Hook to register a tab that auto-unregisters on unmount
4
+ *
5
+ * @example
6
+ * ```tsx
7
+ * function MyFeature() {
8
+ * useRegisterTab({
9
+ * id: 'my-feature-tab',
10
+ * title: 'My Feature',
11
+ * icon: 'Sparkles',
12
+ * view: { type: 'component', component: MyFeaturePanel },
13
+ * });
14
+ *
15
+ * return <div>Feature content...</div>;
16
+ * }
17
+ * ```
18
+ *
19
+ * @param tab - Tab definition object
20
+ */
21
+ export declare function useRegisterTab(tab: TabDefinition): void;
22
+ //# sourceMappingURL=useRegisterTab.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useRegisterTab.d.ts","sourceRoot":"","sources":["../../src/hooks/useRegisterTab.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAiBvD"}
@@ -0,0 +1,7 @@
1
+ export { tabRegistry } from './registry';
2
+ export type { DevToolsContext, DevToolsEvents, PanelPosition, PluginContext, PluginDefinition, TabCategory, TabDefinition, TabViewType, UnregisterFn, } from './types';
3
+ export { registerTab } from './api/registerTab';
4
+ export { createPlugin } from './api/createPlugin';
5
+ export { useDevTools } from './hooks/useDevTools';
6
+ export { useRegisterTab } from './hooks/useRegisterTab';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAGzC,YAAY,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,WAAW,EACX,aAAa,EACb,WAAW,EACX,YAAY,GACb,MAAM,SAAS,CAAC;AAGjB,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,198 @@
1
+ var h = Object.defineProperty;
2
+ var b = (i, t, e) => t in i ? h(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
3
+ var o = (i, t, e) => b(i, typeof t != "symbol" ? t + "" : t, e);
4
+ import { useSyncExternalStore as a, useCallback as u, useRef as d, useEffect as g } from "react";
5
+ class l {
6
+ constructor() {
7
+ o(this, "tabs", /* @__PURE__ */ new Map());
8
+ o(this, "plugins", /* @__PURE__ */ new Map());
9
+ o(this, "listeners", /* @__PURE__ */ new Set());
10
+ o(this, "eventHandlers", /* @__PURE__ */ new Map());
11
+ // State that gets connected to the panel store
12
+ o(this, "_isOpen", !1);
13
+ o(this, "_position", "bottom");
14
+ o(this, "_activeTabId", null);
15
+ // Cached snapshots for useSyncExternalStore (must return same reference if unchanged)
16
+ o(this, "_cachedTabs", []);
17
+ o(this, "_cachedTabsByCategory", {});
18
+ o(this, "_cachedContext", {
19
+ isOpen: !1,
20
+ position: "bottom",
21
+ activeTabId: null
22
+ });
23
+ }
24
+ /**
25
+ * Register a new tab
26
+ * @returns Unregister function to remove the tab
27
+ */
28
+ registerTab(t) {
29
+ return this.tabs.has(t.id) && console.warn(
30
+ `[reactools] Tab with id "${t.id}" already exists. Overwriting.`
31
+ ), this.tabs.set(t.id, {
32
+ category: "custom",
33
+ order: 100,
34
+ ...t
35
+ }), this.notify(), {
36
+ tab: t,
37
+ unregister: () => {
38
+ this.tabs.delete(t.id), this.notify();
39
+ }
40
+ };
41
+ }
42
+ /**
43
+ * Register a plugin with multiple tabs
44
+ * @returns Unregister function to remove the plugin and its tabs
45
+ */
46
+ registerPlugin(t) {
47
+ var s;
48
+ this.plugins.set(t.id, t);
49
+ const e = ((s = t.tabs) == null ? void 0 : s.map(
50
+ (n) => this.registerTab({ ...n, id: `${t.id}:${n.id}` })
51
+ )) ?? [];
52
+ if (t.setup) {
53
+ const n = this.createPluginContext(t.id);
54
+ Promise.resolve(t.setup(n)).catch((c) => {
55
+ console.error(`[reactools] Plugin "${t.id}" setup failed:`, c);
56
+ });
57
+ }
58
+ return {
59
+ plugin: t,
60
+ unregister: () => {
61
+ for (const n of e)
62
+ n.unregister();
63
+ this.plugins.delete(t.id), this.notify();
64
+ }
65
+ };
66
+ }
67
+ /**
68
+ * Get all registered tabs, filtered by visibility
69
+ * Returns cached array for useSyncExternalStore stability
70
+ */
71
+ getTabs() {
72
+ return this._cachedTabs;
73
+ }
74
+ /**
75
+ * Get tabs grouped by category
76
+ * Returns cached object for useSyncExternalStore stability
77
+ */
78
+ getTabsByCategory() {
79
+ return this._cachedTabsByCategory;
80
+ }
81
+ /**
82
+ * Get a tab by ID (including hidden tabs)
83
+ */
84
+ getTabById(t) {
85
+ return this.tabs.get(t);
86
+ }
87
+ /**
88
+ * Rebuild cached tabs (called on changes)
89
+ */
90
+ rebuildCache() {
91
+ this._cachedTabs = Array.from(this.tabs.values()).filter((t) => !t.show || t.show()).sort((t, e) => (t.order ?? 100) - (e.order ?? 100)), this._cachedTabsByCategory = this._cachedTabs.reduce(
92
+ (t, e) => {
93
+ const s = e.category ?? "custom";
94
+ return t[s] || (t[s] = []), t[s].push(e), t;
95
+ },
96
+ {}
97
+ );
98
+ }
99
+ /**
100
+ * Subscribe to registry changes
101
+ */
102
+ subscribe(t) {
103
+ return this.listeners.add(t), () => this.listeners.delete(t);
104
+ }
105
+ /**
106
+ * Subscribe to a specific event
107
+ */
108
+ on(t, e) {
109
+ return this.eventHandlers.has(t) || this.eventHandlers.set(t, /* @__PURE__ */ new Set()), this.eventHandlers.get(t).add(e), () => {
110
+ var s;
111
+ return (s = this.eventHandlers.get(t)) == null ? void 0 : s.delete(e);
112
+ };
113
+ }
114
+ /**
115
+ * Emit an event to all subscribers
116
+ */
117
+ emit(t, e) {
118
+ const s = this.eventHandlers.get(t);
119
+ if (s)
120
+ for (const n of s)
121
+ n(e);
122
+ }
123
+ /**
124
+ * Get the current devtools context
125
+ * Returns cached object for useSyncExternalStore stability
126
+ */
127
+ getContext() {
128
+ return this._cachedContext;
129
+ }
130
+ /**
131
+ * Update the context (called by the panel store)
132
+ */
133
+ setContext(t) {
134
+ const e = this._isOpen, s = this._position, n = this._activeTabId;
135
+ t.isOpen !== void 0 && (this._isOpen = t.isOpen), t.position !== void 0 && (this._position = t.position), t.activeTabId !== void 0 && (this._activeTabId = t.activeTabId), (e !== this._isOpen || s !== this._position || n !== this._activeTabId) && (this._cachedContext = {
136
+ isOpen: this._isOpen,
137
+ position: this._position,
138
+ activeTabId: this._activeTabId
139
+ }), e !== this._isOpen && this.emit(this._isOpen ? "panel:open" : "panel:close", void 0), s !== this._position && this.emit("position:change", { position: this._position }), n !== this._activeTabId && this._activeTabId && this.emit("tab:change", { tabId: this._activeTabId });
140
+ }
141
+ notify() {
142
+ this.rebuildCache();
143
+ for (const t of this.listeners)
144
+ t();
145
+ }
146
+ createPluginContext(t) {
147
+ return {
148
+ registerTab: (e) => this.registerTab({ ...e, id: `${t}:${e.id}` }),
149
+ getContext: () => this.getContext(),
150
+ on: (e, s) => this.on(e, s)
151
+ };
152
+ }
153
+ }
154
+ const r = new l();
155
+ function f(i) {
156
+ return r.registerTab(i);
157
+ }
158
+ function _(i) {
159
+ return r.registerPlugin(i);
160
+ }
161
+ function y() {
162
+ const i = a(
163
+ r.subscribe.bind(r),
164
+ r.getTabs.bind(r),
165
+ r.getTabs.bind(r)
166
+ ), t = a(
167
+ r.subscribe.bind(r),
168
+ r.getTabsByCategory.bind(r),
169
+ r.getTabsByCategory.bind(r)
170
+ ), e = a(
171
+ r.subscribe.bind(r),
172
+ r.getContext.bind(r),
173
+ r.getContext.bind(r)
174
+ ), s = u((n) => r.registerTab(n), []);
175
+ return {
176
+ tabs: i,
177
+ tabsByCategory: t,
178
+ registerTab: s,
179
+ context: e
180
+ };
181
+ }
182
+ function v(i) {
183
+ const t = d(null), e = d(i.id);
184
+ g(() => {
185
+ var s;
186
+ return e.current !== i.id && ((s = t.current) == null || s.call(t), e.current = i.id), t.current = r.registerTab(i).unregister, () => {
187
+ var n;
188
+ (n = t.current) == null || n.call(t);
189
+ };
190
+ }, [i.id, i.title, i.icon, i.category, i.order]);
191
+ }
192
+ export {
193
+ _ as createPlugin,
194
+ f as registerTab,
195
+ r as tabRegistry,
196
+ y as useDevTools,
197
+ v as useRegisterTab
198
+ };
@@ -0,0 +1,79 @@
1
+ import { DevToolsContext, DevToolsEvents, PluginDefinition, TabDefinition } from './types';
2
+ type EventHandler<T> = (payload: T) => void;
3
+ /**
4
+ * Central registry for tabs and plugins
5
+ * This is a singleton that manages all tab registrations and plugin lifecycle
6
+ */
7
+ declare class TabRegistry {
8
+ private tabs;
9
+ private plugins;
10
+ private listeners;
11
+ private eventHandlers;
12
+ private _isOpen;
13
+ private _position;
14
+ private _activeTabId;
15
+ private _cachedTabs;
16
+ private _cachedTabsByCategory;
17
+ private _cachedContext;
18
+ /**
19
+ * Register a new tab
20
+ * @returns Unregister function to remove the tab
21
+ */
22
+ registerTab(tab: TabDefinition): {
23
+ tab: TabDefinition;
24
+ unregister: () => void;
25
+ };
26
+ /**
27
+ * Register a plugin with multiple tabs
28
+ * @returns Unregister function to remove the plugin and its tabs
29
+ */
30
+ registerPlugin(plugin: PluginDefinition): {
31
+ plugin: PluginDefinition;
32
+ unregister: () => void;
33
+ };
34
+ /**
35
+ * Get all registered tabs, filtered by visibility
36
+ * Returns cached array for useSyncExternalStore stability
37
+ */
38
+ getTabs(): TabDefinition[];
39
+ /**
40
+ * Get tabs grouped by category
41
+ * Returns cached object for useSyncExternalStore stability
42
+ */
43
+ getTabsByCategory(): Record<string, TabDefinition[]>;
44
+ /**
45
+ * Get a tab by ID (including hidden tabs)
46
+ */
47
+ getTabById(id: string): TabDefinition | undefined;
48
+ /**
49
+ * Rebuild cached tabs (called on changes)
50
+ */
51
+ private rebuildCache;
52
+ /**
53
+ * Subscribe to registry changes
54
+ */
55
+ subscribe(listener: () => void): () => void;
56
+ /**
57
+ * Subscribe to a specific event
58
+ */
59
+ on<T extends keyof DevToolsEvents>(event: T, handler: EventHandler<DevToolsEvents[T]>): () => void;
60
+ /**
61
+ * Emit an event to all subscribers
62
+ */
63
+ emit<T extends keyof DevToolsEvents>(event: T, payload: DevToolsEvents[T]): void;
64
+ /**
65
+ * Get the current devtools context
66
+ * Returns cached object for useSyncExternalStore stability
67
+ */
68
+ getContext(): DevToolsContext;
69
+ /**
70
+ * Update the context (called by the panel store)
71
+ */
72
+ setContext(context: Partial<DevToolsContext>): void;
73
+ private notify;
74
+ private createPluginContext;
75
+ }
76
+ /** Singleton instance of the tab registry */
77
+ export declare const tabRegistry: TabRegistry;
78
+ export {};
79
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAGd,gBAAgB,EAChB,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAC;AAE5C;;;GAGG;AACH,cAAM,WAAW;IACf,OAAO,CAAC,IAAI,CAAoC;IAChD,OAAO,CAAC,OAAO,CAAuC;IACtD,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,aAAa,CAAiD;IAGtE,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAA2B;IAC5C,OAAO,CAAC,YAAY,CAAuB;IAG3C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,qBAAqB,CAAuC;IACpE,OAAO,CAAC,cAAc,CAIpB;IAEF;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,aAAa;;;;IAuB9B;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,gBAAgB;;;;IA6BvC;;;OAGG;IACH,OAAO,IAAI,aAAa,EAAE;IAI1B;;;OAGG;IACH,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC;IAIpD;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIjD;;OAEG;IACH,OAAO,CAAC,YAAY;IAgBpB;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAK3C;;OAEG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,cAAc,EAC/B,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,YAAY,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GACvC,MAAM,IAAI;IASb;;OAEG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,cAAc,EACjC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GACzB,IAAI;IASP;;;OAGG;IACH,UAAU,IAAI,eAAe;IAI7B;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAmCnD,OAAO,CAAC,MAAM;IAOd,OAAO,CAAC,mBAAmB;CAQ5B;AAED,6CAA6C;AAC7C,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,114 @@
1
+ import { ComponentType } from 'react';
2
+ /** Tab categories for organizing tabs in the sidebar */
3
+ export type TabCategory = "pinned" | "app" | "modules" | "custom";
4
+ /** View types for rendering tab content */
5
+ export type TabViewType = {
6
+ type: "component";
7
+ component: ComponentType;
8
+ } | {
9
+ type: "iframe";
10
+ src: string;
11
+ permissions?: string[];
12
+ } | {
13
+ type: "launch";
14
+ label: string;
15
+ action: () => void | Promise<void>;
16
+ };
17
+ /** Definition for a tab in the devtools panel */
18
+ export interface TabDefinition {
19
+ /** Unique identifier for the tab */
20
+ id: string;
21
+ /** Display name shown in tab bar */
22
+ title: string;
23
+ /** Icon - accepts Lucide icon name or React component */
24
+ icon: string | ComponentType<{
25
+ className?: string;
26
+ }>;
27
+ /** Category for grouping tabs (default: 'custom') */
28
+ category?: TabCategory;
29
+ /** View configuration */
30
+ view: TabViewType;
31
+ /** Order priority within category (lower = higher priority, default: 100) */
32
+ order?: number;
33
+ /** Show badge with count or indicator */
34
+ badge?: number | string | (() => number | string | null);
35
+ /** Conditional rendering - return false to hide tab */
36
+ show?: () => boolean;
37
+ }
38
+ export type RegisterDefinition = {
39
+ plugin: PluginDefinition;
40
+ unregister: UnregisterFn;
41
+ } | {
42
+ tab: TabDefinition;
43
+ unregister: UnregisterFn;
44
+ };
45
+ /** Context provided to plugin setup functions */
46
+ export interface PluginContext {
47
+ /** Register a new tab */
48
+ registerTab: (tab: TabDefinition) => RegisterDefinition;
49
+ /** Get the current devtools context */
50
+ getContext: () => DevToolsContext;
51
+ /** Subscribe to devtools events */
52
+ on: <T extends keyof DevToolsEvents>(event: T, handler: (payload: DevToolsEvents[T]) => void) => () => void;
53
+ }
54
+ /** Definition for a devtools plugin */
55
+ export interface PluginDefinition {
56
+ /** Unique plugin identifier */
57
+ id: string;
58
+ /** Plugin display name */
59
+ name: string;
60
+ /** Plugin version */
61
+ version: string;
62
+ /** Tabs contributed by this plugin */
63
+ tabs?: TabDefinition[];
64
+ /** Setup function called when plugin is registered */
65
+ setup?: (context: PluginContext) => void | Promise<void>;
66
+ }
67
+ /** Current devtools context/state */
68
+ export interface DevToolsContext {
69
+ /** Whether the panel is currently open */
70
+ isOpen: boolean;
71
+ /** Current panel position */
72
+ position: PanelPosition;
73
+ /** Currently active tab ID */
74
+ activeTabId: string | null;
75
+ }
76
+ /** Panel position options */
77
+ export type PanelPosition = "top" | "bottom" | "left" | "right" | "floating";
78
+ /** Events emitted by the devtools panel */
79
+ export interface DevToolsEvents {
80
+ "panel:open": undefined;
81
+ "panel:close": undefined;
82
+ "tab:change": {
83
+ tabId: string;
84
+ };
85
+ "position:change": {
86
+ position: PanelPosition;
87
+ };
88
+ }
89
+ /**
90
+ * Unregister function returned by registerTab(), createPlugin(), or integration setup functions.
91
+ * Pass these to the integrations array in ReactoolsProvider.
92
+ *
93
+ * @example
94
+ * ```tsx
95
+ * import { setupReactQueryIntegration } from '@cpreston321/reactools-integrations/react-query';
96
+ * import { registerTab, createPlugin } from '@cpreston321/reactools-sdk';
97
+ *
98
+ * <ReactoolsProvider config={{
99
+ * integrations: [
100
+ * // Integration setup functions (called)
101
+ * setupReactQueryIntegration(),
102
+ * setupReactRouterIntegration(),
103
+ *
104
+ * // Direct tab registration
105
+ * registerTab({ id: 'my-tab', title: 'My Tab', icon: 'Code', view: { type: 'component', component: MyTab } }),
106
+ *
107
+ * // Direct plugin registration
108
+ * createPlugin({ id: 'my-plugin', name: 'My Plugin', version: '1.0.0', tabs: [...] }),
109
+ * ]
110
+ * }}>
111
+ * ```
112
+ */
113
+ export type UnregisterFn = () => void;
114
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAE3C,wDAAwD;AACxD,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;AAElE,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,aAAa,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC;AAE1E,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,oCAAoC;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,IAAI,EAAE,MAAM,GAAG,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrD,qDAAqD;IACrD,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,yBAAyB;IACzB,IAAI,EAAE,WAAW,CAAC;IAClB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,CAAC;IACzD,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,OAAO,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAC1B;IACE,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,YAAY,CAAC;CAC1B,GACD;IACE,GAAG,EAAE,aAAa,CAAC;IACnB,UAAU,EAAE,YAAY,CAAC;CAC1B,CAAC;AAEN,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,WAAW,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,kBAAkB,CAAC;IACxD,uCAAuC;IACvC,UAAU,EAAE,MAAM,eAAe,CAAC;IAClC,mCAAmC;IACnC,EAAE,EAAE,CAAC,CAAC,SAAS,MAAM,cAAc,EACjC,KAAK,EAAE,CAAC,EACR,OAAO,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,IAAI,KAC1C,MAAM,IAAI,CAAC;CACjB;AAED,uCAAuC;AACvC,MAAM,WAAW,gBAAgB;IAC/B,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAC;IACvB,sDAAsD;IACtD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1D;AAED,qCAAqC;AACrC,MAAM,WAAW,eAAe;IAC9B,0CAA0C;IAC1C,MAAM,EAAE,OAAO,CAAC;IAChB,6BAA6B;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,8BAA8B;IAC9B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,6BAA6B;AAC7B,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE7E,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,SAAS,CAAC;IACxB,aAAa,EAAE,SAAS,CAAC;IACzB,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAChC,iBAAiB,EAAE;QAAE,QAAQ,EAAE,aAAa,CAAA;KAAE,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC"}
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "@cpreston321/reactools-sdk",
3
+ "version": "0.1.2",
4
+ "type": "module",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ },
13
+ "./types": {
14
+ "types": "./dist/types.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "peerDependencies": {
21
+ "react": "^18.0.0 || ^19.0.0"
22
+ },
23
+ "devDependencies": {
24
+ "@types/react": "^18.3.12",
25
+ "react": "^18.3.1",
26
+ "vite": "^6.0.3",
27
+ "vite-plugin-dts": "^4.3.0"
28
+ },
29
+ "scripts": {
30
+ "dev": "vite build --watch",
31
+ "build": "vite build",
32
+ "typecheck": "tsc --noEmit",
33
+ "clean": "rm -rf dist"
34
+ }
35
+ }