
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
@sucoza/plugin-core
Advanced tools
Core infrastructure and base classes for building TanStack DevTools plugins. This package provides the essential building blocks for creating powerful, consistent DevTools plugins.
npm install @sucoza/plugin-core
# or
yarn add @sucoza/plugin-core
# or
pnpm add @sucoza/plugin-core
import { BaseDevToolsPlugin, usePluginState } from '@sucoza/plugin-core';
interface MyPluginState {
items: string[];
selectedItem: string | null;
}
class MyDevToolsPlugin extends BaseDevToolsPlugin<MyPluginState> {
constructor() {
super({
name: 'My DevTools Plugin',
version: '1.0.0',
namespace: 'my-plugin'
});
}
protected getInitialState(): MyPluginState {
return {
items: [],
selectedItem: null
};
}
protected onActivate(): void {
// Plugin activation logic
this.startMonitoring();
}
protected onDeactivate(): void {
// Plugin deactivation logic
this.stopMonitoring();
}
private startMonitoring(): void {
// Start collecting data
this.updateState({
items: ['item1', 'item2', 'item3']
});
}
private stopMonitoring(): void {
// Stop collecting data
}
}
export const myPlugin = new MyDevToolsPlugin();
import React from 'react';
import { usePluginState, PluginPanel } from '@sucoza/plugin-core';
import { myPlugin } from './my-plugin';
export function MyPluginPanel() {
const { state, actions } = usePluginState(myPlugin);
return (
<PluginPanel
title="My Plugin"
plugin={myPlugin}
>
<div>
<h3>Items ({state.items.length})</h3>
<ul>
{state.items.map((item, index) => (
<li
key={index}
onClick={() => actions.updateState({ selectedItem: item })}
style={{
backgroundColor: state.selectedItem === item ? '#e3f2fd' : 'transparent'
}}
>
{item}
</li>
))}
</ul>
</div>
</PluginPanel>
);
}
import { BaseDevToolsPlugin, PluginLifecycle } from '@sucoza/plugin-core';
class MyPlugin extends BaseDevToolsPlugin implements PluginLifecycle {
// Called when plugin is first loaded
async onInitialize(): Promise<void> {
console.log('Plugin initialized');
}
// Called when plugin becomes active
protected onActivate(): void {
console.log('Plugin activated');
}
// Called when plugin becomes inactive
protected onDeactivate(): void {
console.log('Plugin deactivated');
}
// Called when plugin is being destroyed
async onDestroy(): Promise<void> {
console.log('Plugin destroyed');
}
}
import { EventEmitter, PluginEvent } from '@sucoza/plugin-core';
// Emit custom events
myPlugin.emit('data-updated', {
timestamp: Date.now(),
items: newItems
});
// Listen to events
myPlugin.on('data-updated', (event: PluginEvent<{ items: string[] }>) => {
console.log('Data updated:', event.data.items);
});
// One-time event listener
myPlugin.once('initialized', () => {
console.log('Plugin ready!');
});
import { usePluginState, StateAction } from '@sucoza/plugin-core';
function MyComponent() {
const {
state,
actions,
isLoading,
error,
reset
} = usePluginState(myPlugin);
// Update state
const handleAddItem = (newItem: string) => {
actions.updateState({
items: [...state.items, newItem]
});
};
// Batch state updates
const handleBatchUpdate = () => {
actions.batchUpdate([
{ items: [...state.items, 'new1'] },
{ selectedItem: 'new1' }
]);
};
return (
<div>
{isLoading && <p>Loading...</p>}
{error && <p>Error: {error}</p>}
<button onClick={() => handleAddItem('new item')}>
Add Item
</button>
<button onClick={() => reset()}>
Reset State
</button>
</div>
);
}
Core abstract class for all DevTools plugins.
interface PluginOptions {
name: string;
version: string;
namespace: string;
enabled?: boolean;
debug?: boolean;
autoActivate?: boolean;
}
| Method | Description |
|---|---|
activate() | Activates the plugin |
deactivate() | Deactivates the plugin |
isActive() | Returns plugin activation status |
getState() | Returns current plugin state |
updateState(update) | Updates plugin state |
emit(event, data) | Emits a plugin event |
on(event, handler) | Subscribes to plugin events |
off(event, handler) | Unsubscribes from events |
destroy() | Destroys the plugin |
| Method | Description |
|---|---|
getInitialState() | Returns initial plugin state |
onActivate() | Called when plugin activates |
onDeactivate() | Called when plugin deactivates |
React hook for accessing plugin state and actions.
Returns:
{
state: T; // Current plugin state
actions: {
updateState: (update: Partial<T>) => void;
batchUpdate: (updates: Partial<T>[]) => void;
reset: () => void;
};
isLoading: boolean; // Plugin loading status
error: string | null; // Current error state
isActive: boolean; // Plugin activation status
reset: () => void; // Reset to initial state
}
Hook for subscribing to plugin events.
const events = usePluginEvents(myPlugin, {
'data-updated': (data) => console.log('Data:', data),
'error': (error) => console.error('Error:', error)
});
Hook for managing plugin lifecycle.
const {
activate,
deactivate,
isActive,
isInitialized
} = usePluginLifecycle(myPlugin);
Standard panel component for plugin UI.
<PluginPanel
title="My Plugin"
plugin={myPlugin}
toolbar={<MyToolbar />}
onClose={() => console.log('Panel closed')}
>
<MyPluginContent />
</PluginPanel>
Context provider for plugin state management.
<PluginProvider plugin={myPlugin}>
<MyPluginComponents />
</PluginProvider>
Error boundary component with plugin integration.
<ErrorBoundary
plugin={myPlugin}
fallback={<div>Plugin Error</div>}
>
<MyPluginContent />
</ErrorBoundary>
// Plugin lifecycle events
interface PluginLifecycleEvents {
'plugin:initialized': { plugin: BaseDevToolsPlugin };
'plugin:activated': { plugin: BaseDevToolsPlugin };
'plugin:deactivated': { plugin: BaseDevToolsPlugin };
'plugin:destroyed': { plugin: BaseDevToolsPlugin };
'plugin:error': { plugin: BaseDevToolsPlugin; error: Error };
}
// State management events
interface PluginStateEvents {
'state:updated': { state: any; previousState: any };
'state:reset': { state: any };
'state:error': { error: Error };
}
import { PluginRegistry } from '@sucoza/plugin-core';
const registry = new PluginRegistry();
// Register plugins
registry.register(myPlugin);
registry.register(anotherPlugin);
// Get all plugins
const allPlugins = registry.getAll();
// Get plugin by namespace
const plugin = registry.get('my-plugin');
// Check if plugin exists
const exists = registry.has('my-plugin');
// Plugin A emits data
pluginA.emit('data-available', { data: myData });
// Plugin B listens for data
pluginB.on('plugin:data-available', (event) => {
if (event.source === 'pluginA') {
// Handle data from Plugin A
console.log('Received data:', event.data);
}
});
import { PluginMiddleware } from '@sucoza/plugin-core';
const loggingMiddleware: PluginMiddleware = (plugin, next) => {
return (action) => {
console.log('Action:', action.type);
const result = next(action);
console.log('State after action:', plugin.getState());
return result;
};
};
myPlugin.use(loggingMiddleware);
Check out the examples/ directory for complete plugin implementations and usage patterns.
git checkout -b feature/plugin-improvement)git commit -m 'Add plugin feature')git push origin feature/plugin-improvement)MIT © tyevco
Part of the @sucoza TanStack DevTools ecosystem.
FAQs
Core infrastructure for TanStack DevTools plugins
We found that @sucoza/plugin-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.