
Research
SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.
@blac/react
Advanced tools
React integration for the BlaC state management library with automatic re-render optimization.
React integration for the BlaC state management library with automatic re-render optimization.
npm install @blac/react @blac/core
# or
pnpm add @blac/react @blac/core
# or
yarn add @blac/react @blac/core
import { Cubit } from '@blac/core';
import { useBloc } from '@blac/react';
class CounterCubit extends Cubit<{ count: number }> {
constructor() {
super({ count: 0 });
}
increment = () => this.emit({ count: this.state.count + 1 });
decrement = () => this.emit({ count: this.state.count - 1 });
}
function Counter() {
const [state, counter] = useBloc(CounterCubit);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={counter.increment}>+</button>
<button onClick={counter.decrement}>-</button>
</div>
);
}
Connects a component to a state container with automatic re-renders on state changes.
const [state, bloc, ref] = useBloc(MyBloc);
Returns: [state, bloc, ref]
state - Current state (reactive)bloc - The bloc instance for calling methodsref - Component reference for isolated instancesAuto-tracking (default): Automatically detects which properties you access and only re-renders when those change.
function UserProfile() {
const [state, user] = useBloc(UserBloc);
// Only re-renders when state.name changes
// (state.email changes won't cause re-render)
return <h1>{state.name}</h1>;
}
Manual dependencies: Explicit dependency array like useEffect.
function Counter() {
const [state] = useBloc(CounterBloc, {
dependencies: (state) => [state.count],
});
return <p>{state.count}</p>;
}
No tracking: Returns full state, re-renders on any change.
function FullState() {
const [state] = useBloc(MyBloc, { autoTrack: false });
return <pre>{JSON.stringify(state)}</pre>;
}
useBloc(MyBloc, {
// Tracking mode
autoTrack: true, // Enable/disable auto-tracking (default: true)
dependencies: (state) => [state.prop], // Manual dependencies
// Instance management
instanceId: 'unique-id', // Custom instance identifier
// Lifecycle callbacks
onMount: (bloc) => console.log('Mounted', bloc),
onUnmount: (bloc) => console.log('Unmounted', bloc),
});
Connects to a state container without subscribing to state changes. Use for calling actions without re-renders, or for stateless containers.
const bloc = useBlocActions(MyBloc);
Use cases:
// Stateless services (analytics, navigation, etc.)
function TrackButton() {
const analytics = useBlocActions(AnalyticsService);
return (
<button onClick={() => analytics.trackClick('button')}>Click me</button>
);
}
// Actions-only (no state subscription)
function IncrementButton() {
const counter = useBlocActions(CounterCubit);
return <button onClick={counter.increment}>+</button>;
}
useBlocActions(MyBloc, {
instanceId: 'unique-id', // Custom instance identifier
onMount: (bloc) => bloc.initialize(),
onUnmount: (bloc) => bloc.cleanup(),
});
By default, all components using the same bloc class share one instance:
function ComponentA() {
const [state] = useBloc(CounterCubit);
// Uses shared instance
}
function ComponentB() {
const [state] = useBloc(CounterCubit);
// Uses same shared instance
}
For component-scoped state, use the @blac({ isolated: true }) decorator:
import { Cubit, blac } from '@blac/core';
@blac({ isolated: true })
class FormCubit extends Cubit<FormState> {
// ...
}
function FormA() {
const [state] = useBloc(FormCubit);
// Gets its own instance
}
function FormB() {
const [state] = useBloc(FormCubit);
// Gets a different instance
}
Share instances across specific components with instanceId:
function EditorA() {
const [state] = useBloc(EditorCubit, { instanceId: 'editor-1' });
}
function EditorB() {
const [state] = useBloc(EditorCubit, { instanceId: 'editor-1' });
// Same instance as EditorA
}
function EditorC() {
const [state] = useBloc(EditorCubit, { instanceId: 'editor-2' });
// Different instance
}
Configure global behavior:
import { configureBlacReact } from '@blac/react';
configureBlacReact({
autoTrack: true, // Enable auto-tracking by default (default: true)
});
function useBloc<T extends StateContainerConstructor>(
BlocClass: T,
options?: UseBlocOptions<T>,
): [ExtractState<T>, InstanceType<T>, ComponentRef];
function useBlocActions<T extends StateContainerConstructor>(
BlocClass: T,
options?: UseBlocActionsOptions<InstanceType<T>>,
): InstanceType<T>;
| Option | Type | Description |
|---|---|---|
autoTrack | boolean | Enable auto-tracking (default: true) |
dependencies | (state) => any[] | Manual dependency selector |
instanceId | string | number | Custom instance identifier |
onMount | (bloc) => void | Called when component mounts |
onUnmount | (bloc) => void | Called when component unmounts |
| Option | Type | Description |
|---|---|---|
instanceId | string | number | Custom instance identifier |
onMount | (bloc) => void | Called when component mounts |
onUnmount | (bloc) => void | Called when component unmounts |
useSyncExternalStoreMIT
FAQs
> ⚠️ **Warning:** This project is currently under active development. The API may change in future releases. Use with caution in production environments.
The npm package @blac/react receives a total of 139 weekly downloads. As such, @blac/react popularity was classified as not popular.
We found that @blac/react 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.

Research
An emerging npm supply chain attack that infects repos, steals CI secrets, and targets developer AI toolchains for further compromise.

Company News
Socket is proud to join the OpenJS Foundation as a Silver Member, deepening our commitment to the long-term health and security of the JavaScript ecosystem.

Security News
npm now links to Socket's security analysis on every package page. Here's what you'll find when you click through.