0.5.16 • Published 5 months ago

@pumped-fn/react v0.5.16

Weekly downloads
-
License
MIT
Repository
github
Last release
5 months ago

@pumped-fn/react

React bindings for Pumped Functions.

Installation

npm install @pumped-fn/react @pumped-fn/core-next
# or
yarn add @pumped-fn/react @pumped-fn/core-next
# or
pnpm add @pumped-fn/react @pumped-fn/core-next

API Documentation

Components

ScopeProvider

Provides a scope context for all child components to access the same scope.

import { ScopeProvider } from '@pumped-fn/react';
import { createScope } from '@pumped-fn/core-next';

// Optional: create a custom scope
const scope = createScope();

function App() {
  return (
    <ScopeProvider scope={scope}>
      {/* Your application components */}
    </ScopeProvider>
  );
}

Resolve

A component that resolves an executor and passes the value to its children.

import { Resolve } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);

function Counter() {
  return (
    <Resolve e={countExecutor}>
      {(count) => <div>Count: {count}</div>}
    </Resolve>
  );
}

Resolves

A component that resolves multiple executors and passes the values to its children.

import { Resolves } from '@pumped-fn/react';
import { provide, derive } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);
const doubleCount = derive([countExecutor.reactive], ([count]) => count * 2);

function CounterWithDouble() {
  return (
    <Resolves e={[countExecutor, doubleCount]}>
      {([count, double]) => (
        <div>
          <div>Count: {count}</div>
          <div>Double: {double}</div>
        </div>
      )}
    </Resolves>
  );
}

Reselect

A component that resolves an executor, applies a selector function, and passes the result to its children.

import { Reselect } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const userExecutor = provide(() => ({ name: 'John', age: 30 }));

function UserName() {
  return (
    <Reselect 
      e={userExecutor} 
      selector={(user) => user.name}
    >
      {(name) => <div>Name: {name}</div>}
    </Reselect>
  );
}

Reactives

A component that resolves multiple reactive executors and passes the values to its children.

import { Reactives } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);
const nameExecutor = provide(() => 'John');

function ReactiveExample() {
  return (
    <Reactives e={[countExecutor, nameExecutor]}>
      {([count, name]) => (
        <div>
          <div>Count: {count}</div>
          <div>Name: {name}</div>
        </div>
      )}
    </Reactives>
  );
}

Effect

A component that resolves executors for side effects without rendering anything.

import { Effect } from '@pumped-fn/react';
import { provide, derive } from '@pumped-fn/core-next';

const loggerExecutor = derive([], () => {
  console.log('Logger initialized');
  return null;
});

function Logger() {
  return <Effect e={[loggerExecutor]} />;
}

Hooks

useScope

Returns the current scope from the nearest ScopeProvider.

import { useScope } from '@pumped-fn/react';

function MyComponent() {
  const scope = useScope();
  // Use scope methods directly
  return null;
}

useResolve

Resolves an executor and returns its value. Can optionally apply a selector function.

import { useResolve } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);

function Counter() {
  // Basic usage
  const count = useResolve(countExecutor);
  
  // With selector
  const isEven = useResolve(countExecutor, (count) => count % 2 === 0);
  
  return (
    <div>
      <div>Count: {count}</div>
      <div>Is even: {isEven ? 'Yes' : 'No'}</div>
    </div>
  );
}

useResolveMany

Resolves multiple executors and returns their values as an array.

import { useResolveMany } from '@pumped-fn/react';
import { provide, derive } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);
const doubleCount = derive([countExecutor.reactive], ([count]) => count * 2);

function CounterWithDouble() {
  const [count, double] = useResolveMany(countExecutor, doubleCount);
  
  return (
    <div>
      <div>Count: {count}</div>
      <div>Double: {double}</div>
    </div>
  );
}

useUpdate

Returns a function that can update an executor's value.

import { useResolve, useUpdate } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);

function Counter() {
  const count = useResolve(countExecutor);
  const updateCount = useUpdate(countExecutor);
  
  const increment = () => {
    // Direct value update
    updateCount(count + 1);
    
    // Or with function update
    updateCount((current) => current + 1);
  };
  
  return (
    <div>
      <div>Count: {count}</div>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

useReset

Returns a function that resets an executor to its initial value.

import { useResolve, useReset } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);

function Counter() {
  const count = useResolve(countExecutor);
  const resetCount = useReset(countExecutor);
  
  return (
    <div>
      <div>Count: {count}</div>
      <button onClick={resetCount}>Reset</button>
    </div>
  );
}

useRelease

Returns a function that releases an executor from the scope.

import { useResolve, useRelease } from '@pumped-fn/react';
import { provide } from '@pumped-fn/core-next';

const countExecutor = provide(() => 0);

function Counter() {
  const count = useResolve(countExecutor);
  const releaseCount = useRelease(countExecutor);
  
  return (
    <div>
      <div>Count: {count}</div>
      <button onClick={releaseCount}>Release</button>
    </div>
  );
}

TypeScript Types

Component Props

// ScopeProvider props
type ScopeProviderProps = {
  children: React.ReactNode;
  scope?: Core.Scope;
};

// Resolve props
type ResolveProps<T> = {
  e: Core.Executor<T>;
  children: (props: T) => React.ReactNode | React.ReactNode[];
};

// Resolves props
type ResolvesProps<T extends Core.BaseExecutor<unknown>[]> = {
  e: { [K in keyof T]: T[K] };
  children: (props: { [K in keyof T]: Core.InferOutput<T[K]> }) =>
    | React.ReactNode
    | React.ReactNode[];
};

// Reselect props
type ReselectProps<T, K> = {
  e: Core.Executor<T>;
  selector: (value: T) => K;
  children: (props: K) => React.ReactNode | React.ReactNode[];
  equality?: (thisValue: T, thatValue: T) => boolean;
};

// Reactives props
type ReactivesProps<T extends Core.Executor<unknown>[]> = {
  e: { [K in keyof T]: T[K] };
  children: (props: { [K in keyof T]: Core.InferOutput<T[K]> }) =>
    | React.ReactNode
    | React.ReactNode[];
};

// Effect props
type EffectProps = {
  e: Core.Executor<unknown>[];
};

Hook Types

// useResolve options
type UseResolveOption<T> = {
  snapshot?: (value: T) => T;
  equality?: (thisValue: T, thatValue: T) => boolean;
};

// useResolve return type
function useResolve<T extends Core.BaseExecutor<unknown>>(
  executor: T
): Core.InferOutput<T>;

function useResolve<T extends Core.BaseExecutor<unknown>, K>(
  executor: T,
  selector: (value: Core.InferOutput<T>) => K,
  options?: UseResolveOption<T>
): K;

// useResolveMany return type
function useResolveMany<T extends Array<Core.BaseExecutor<unknown>>>(
  ...executors: { [K in keyof T]: T[K] }
): { [K in keyof T]: Core.InferOutput<T[K]> };

// useUpdate return type
function useUpdate<T>(
  executor: Core.Executor<T>
): (updateFn: T | ((current: T) => T)) => void;

// useReset return type
function useReset(executor: Core.Executor<unknown>): () => void;

// useRelease return type
function useRelease(executor: Core.Executor<unknown>): () => void;

Integration with @pumped-fn/core-next

This package is designed to work with @pumped-fn/core-next and provides React bindings for the core functionality. The main concepts from the core package that you'll use with these React bindings are:

  • provide: Creates a new executor with an initial value
  • derive: Creates a derived executor based on other executors
  • createScope: Creates a new scope for managing executors

For more information on these core concepts, refer to the @pumped-fn/core-next documentation.

License

MIT

0.5.16

5 months ago

0.5.15

6 months ago

0.5.14

6 months ago

0.5.13

6 months ago

0.5.10

6 months ago

0.5.9

6 months ago

0.5.8

6 months ago

0.5.7

6 months ago

0.5.6

8 months ago

0.5.5

8 months ago

0.5.4

8 months ago

0.5.3

8 months ago

0.5.2

9 months ago

0.5.0

9 months ago