
Research
Two Malicious Rust Crates Impersonate Popular Logger to Steal Wallet Keys
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
@fleur/lys
Advanced tools
Lys (risu) is an minimal statement manger for '21s React.
It's focus to Per page state management, not application global state management.
Lys is usable to instead of useReducer
, Mobx
, or Recoil
if you have async procedure.
yarn add @fleur/lys
Next.js
, useSWR
Summary in CodeSandbox Example.
First, define your slice.
import { createSlice } from '@fleur/lys';
const formSlice = createSlice({
actions: {
// Define actions
async patchItem({ commit }, index: number, patch: Partial<State['form']['items'][0]>) {
commit((draft) => {
Object.assign(draft.form.items[index], patch);
});
},
async submit({ state, commit }) {
if (state.hasError) return;
commit({ submitting: true });
commit({
submiting: false,
form: await (
await fetch('/api/users', { body: JSON.stringify(state.form) })
).json(),
});
},
async validate({ state }) {
commit({ hasError: false });
// Use your favorite validator
commit({ hasError: await validateForm(state.form) });
},
},
computed: {
// You can define computable values in `computed`
// `computed` is cached between to next state changed
itemOf: (state) => (index: number) => state.form.items[index],
canSubmit: (state) => !state.submitting,
},
}, (): State => ({
// Define initial state
submitting: false,
hasError: false,
form: {
id: null,
username: "",
items: [{ name: "" }],
},
})
);
Next, initialize slice on your page component
import { useLysSliceRoot, useLysSlice } from '@fleur/lys';
export const NewUserPage = () => {
const { data: initialData, error } = useSWR('/users/1', fetcher);
// Initialize slice by `useLysSliceRoot`
// `initialState` in second argument, it shallow override to Slice's initial state.
// `initialData` is re-evaluated when it changes from null or undefined to something else.
//
// Or can you define `fetchUser` in slice and call it in `useEffect()`
const [state, actions] = useLysSliceRoot(
formSlice,
initialData ? { form: initialData } : null
);
const handleChangeName = useCallback(({ currentTarget }) => {
// `set` is builtin action
actions.set((draft) => {
draft.form.username = currentTarget.value;
});
}, []);
const handleSubmit = useCallback(async () => {
await actions.validate();
await actions.submit();
}, []);
return (
<div>
<label>
Display name:
<input type="text" value={state.form.name} onChange={handleChangeName} />
</label>
<h1>Your items</h1>
{state.form.items.map((index) => (
<Item index={index} />
))}
<button disabled={!state.canSubmit} onClick={handleSubmit}>
Register
</button>
</div>
);
};
Use initialize slice into child component
// In child component
const Item = ({ index }) => {
// Use slice from root component by `useLysSlice`
const [state, actions] = useLysSlice(formSlice);
const item = state.itemOf(index);
const handleChangeName = useCallback(({ currentTarget }) => {
// Can call action from child component and share state with root.
// Re-rendering from root (no duplicate re-rendering)
actions.patchItem(index, { name: currentTarget.value });
}, []);
return (
<div>
Item of #{index + 1}
<label>
Name: <input type="text" value={item.name} />
</label>
</div>
);
};
Lys's Slice is very testable. Let look testing example!
import { instantiateSlice, createSlice } from "@fleur/lys";
// Define (Normally, import from other file)
const slice = createSlice(
{
actions: {
increment({ commit }) {
commit((draft) => draft.count++);
},
},
computed: {
isZero: (state) => state.count === 0,
},
},
() => ({ count: 0, submitting: false })
);
describe("Testing slice", () => {
it("Should increment one", async () => {
// instantiate
const { state, actions } = instantiateSlice(slice);
// Expection
expect(state.current.count).toBe(0);
expect(state.current.isZero).toBe(true);
await actions.increment();
expect(state.current.count).toBe(1);
expect(state.current.isZero).toBe(false);
});
it("mock slice actions (for component testing)", () => {
const actionSpy = jest.fn(({ state }) => (state.count = 10));
const { state, actions } = mockSlice(
slice,
{
/* part of initial state here */
},
{
/* Mock action implementations here */
increment: actionSpy,
}
);
actions.increment();
expect(actionSpy).toBeCalled();
});
});
FAQs
lys is an micro statement manager for '21s react
We found that @fleur/lys demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 4 open source maintainers 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
Socket uncovers malicious Rust crates impersonating fast_log to steal Solana and Ethereum wallet keys from source code.
Research
A malicious package uses a QR code as steganography in an innovative technique.
Research
/Security News
Socket identified 80 fake candidates targeting engineering roles, including suspected North Korean operators, exposing the new reality of hiring as a security function.