@pyreon/attrs 0.29.0 → 0.32.0

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 CHANGED
@@ -139,7 +139,7 @@ Use `ExtractProps<typeof Button>` from `@pyreon/core` to recover the union when
139
139
 
140
140
  ## Documentation
141
141
 
142
- Full docs: [docs.pyreon.dev/docs/attrs](https://docs.pyreon.dev/docs/attrs) (or `docs/docs/attrs.md` in this repo).
142
+ Full docs: [docs.pyreon.dev/docs/attrs](https://docs.pyreon.dev/docs/attrs) (or `docs/src/content/docs/attrs.md` in this repo).
143
143
 
144
144
  ## License
145
145
 
package/lib/index.js CHANGED
@@ -1,16 +1,7 @@
1
1
  import { compose, hoistNonReactStatics, isEmpty, omit, pick } from "@pyreon/ui-core";
2
- import { mergeProps } from "@pyreon/core";
2
+ import { mergeProps, removeUndefinedProps } from "@pyreon/core";
3
3
 
4
4
  //#region src/utils/attrs.ts
5
- const removeUndefinedProps = ((props) => {
6
- const result = {};
7
- const descriptors = Object.getOwnPropertyDescriptors(props);
8
- for (const key of Object.keys(descriptors)) {
9
- const d = descriptors[key];
10
- if (d.get || d.value !== void 0) Object.defineProperty(result, key, d);
11
- }
12
- return result;
13
- });
14
5
  const calculateChainOptions = (options) => (args) => {
15
6
  const result = {};
16
7
  if (!options || isEmpty(options)) return result;
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["attrsHoc"],"sources":["../src/utils/attrs.ts","../src/hoc/attrsHoc.ts","../src/utils/chaining.ts","../src/utils/compose.ts","../src/utils/statics.ts","../src/attrs.ts","../src/init.ts","../src/isAttrsComponent.ts","../src/index.ts"],"sourcesContent":["import { isEmpty } from '@pyreon/ui-core'\n\n/**\n * Strips keys with `undefined` values from a props object.\n * This prevents undefined consumer props from overriding defaults\n * computed by `.attrs()` callbacks. Only explicitly set values\n * (including `null`) should override defaults.\n *\n * **Descriptor-copy contract** — uses\n * `Object.getOwnPropertyDescriptors(props)` + `Object.defineProperty`\n * to forward getter-shaped reactive props (`_rp(() => signal())`\n * brands that `makeReactiveProps` converts to property getters)\n * without firing them. A plain `result[key] = props[key]` value-copy\n * would fire each getter at HOC setup time, capture the resolved\n * value, and store it as a data property — collapsing the live\n * subscription to a one-shot snapshot. The downstream `applyProp` /\n * `_bind` then has nothing reactive to track. This is the same\n * contract `@pyreon/rocketstyle/src/utils/attrs.ts:removeUndefinedProps`\n * has held since PR #584; the `@pyreon/attrs` copy here was\n * historically value-copy and silently broke reactive-prop\n * forwarding for any consumer using `attrs(Component)` directly\n * (without rocketstyle wrapping).\n */\ntype RemoveUndefinedProps = <T extends Record<string, any>>(\n props: T,\n) => { [I in keyof T as T[I] extends undefined ? never : I]: T[I] }\n\nexport const removeUndefinedProps = (<T extends Record<string, any>>(props: T) => {\n const result: Record<string, unknown> = {}\n const descriptors = Object.getOwnPropertyDescriptors(props)\n for (const key of Object.keys(descriptors)) {\n const d = descriptors[key] as PropertyDescriptor\n // Keep getter-shaped descriptors verbatim (reactive props). For data\n // descriptors, filter `value === undefined` (matches the previous\n // value-copy semantic — undefined values from consumers must not\n // shadow `.attrs()` defaults).\n if (d.get || d.value !== undefined) {\n Object.defineProperty(result, key, d)\n }\n }\n return result\n}) as RemoveUndefinedProps\n\n/**\n * Reduces an array of option functions (from chained `.attrs()` calls)\n * into a single merged result. Each function is called with `args`\n * (typically the current props) and its return value is merged\n * left-to-right via Object.assign — so later `.attrs()` calls\n * override earlier ones.\n *\n * Returns a curried function: first call binds the chain, second\n * call provides the arguments and executes the reduction.\n *\n * Uses `Object.assign` (not `mergeProps`) because `.attrs()`\n * callbacks always return freshly-constructed object literals — the\n * keys flowing through here are written by the callback as plain\n * data properties (no getters). The reactivity-preservation\n * concern only applies to props flowing IN from the consumer\n * (handled by `removeUndefinedProps` + `mergeProps` from `@pyreon/core`\n * in the HOC's prop-merge step).\n */\ntype OptionFunc<A> = (...arg: A[]) => Record<string, unknown>\ntype CalculateChainOptions = <A>(\n options?: OptionFunc<A>[],\n) => (args: A[]) => ReturnType<OptionFunc<A>>\n\nexport const calculateChainOptions: CalculateChainOptions = (options) => (args) => {\n const result = {}\n if (!options || isEmpty(options)) return result\n\n return options.reduce((acc, item) => Object.assign(acc, item(...args)), {})\n}\n","import { mergeProps } from '@pyreon/core'\nimport type { Configuration } from '../types/configuration'\nimport type { ComponentFn } from '../types/utils'\nimport { calculateChainOptions, removeUndefinedProps } from '../utils/attrs'\n\nexport type AttrsStyleHOC = ({\n attrs,\n priorityAttrs,\n}: Pick<Configuration, 'attrs' | 'priorityAttrs'>) => (\n WrappedComponent: ComponentFn<any>,\n) => ComponentFn<any>\n\n/**\n * Creates the core HOC that computes default props from the `.attrs()` chain.\n *\n * This is always the outermost HOC in the compose chain, so it runs first.\n * It resolves both priority and normal attrs callbacks, then merges them\n * with the consumer's explicit props following this precedence:\n *\n * priorityAttrs < normalAttrs < explicit props (last wins)\n *\n * In Pyreon, components are plain functions — no forwardRef needed.\n * The ref flows as a normal prop through the chain.\n */\nconst createAttrsHOC: AttrsStyleHOC = ({ attrs, priorityAttrs }) => {\n // Pre-build the chain reducers once (not per render).\n const calculateAttrs = calculateChainOptions(attrs)\n const calculatePriorityAttrs = calculateChainOptions(priorityAttrs)\n // Most components never call .attrs() — short-circuit the merge work below\n // so the no-chain mount path skips 2 reducer invocations + 3 object spreads.\n // Mirrors vitus-labs's attrsHoc fast-path; React-side memoization\n // (useMemo / useStableValue) is omitted because Pyreon components run once\n // per mount, not on every render.\n const hasAttrs = (attrs?.length ?? 0) > 0\n const hasPriorityAttrs = (priorityAttrs?.length ?? 0) > 0\n const hasAnyChain = hasAttrs || hasPriorityAttrs\n\n const attrsHoc = (WrappedComponent: ComponentFn<any>) => {\n const HOCComponent: ComponentFn<any> = (props) => {\n // Strip undefined values so they don't shadow defaults from attrs callbacks.\n const filteredProps = removeUndefinedProps(props)\n\n // Fast path: no attrs configured — skip reducers + spreads entirely.\n if (!hasAnyChain) return WrappedComponent(filteredProps)\n\n // 1. Resolve priority attrs (lowest precedence defaults).\n const prioritizedAttrs = hasPriorityAttrs\n ? calculatePriorityAttrs([filteredProps])\n : null\n // 2. Resolve normal attrs — these see priority + explicit props as input.\n //\n // The argument passed INTO `.attrs()` callbacks must preserve getter\n // descriptors on filteredProps, so any callback that reads a reactive\n // prop (e.g. `(p) => ({ x: p.someSignalDrivenProp + 1 })`) reads the\n // live value, not a one-shot snapshot. Plain spread `{ …priority,\n // …filteredProps }` would fire every getter at this site — that was\n // the pre-fix shape that silently broke reactivity for direct\n // `attrs(Component)` consumers.\n const finalAttrs = hasAttrs\n ? calculateAttrs([\n prioritizedAttrs\n ? mergeProps(prioritizedAttrs, filteredProps)\n : filteredProps,\n ])\n : null\n\n // 3. Merge: priority < normal attrs < explicit props (last wins).\n // Use canonical `mergeProps` from @pyreon/core (not spread) so the\n // explicit-props level keeps any getter-shaped reactive props live\n // all the way to the wrapped component. `prioritizedAttrs` and\n // `finalAttrs` always come from freshly-constructed object literals\n // (in user `.attrs()` callbacks), so they carry no getters —\n // descriptor-copy is a no-op cost there.\n //\n // `mergeProps` does NOT accept null/undefined sources (unlike the\n // legacy `mergeDescriptors` it replaces). `prioritizedAttrs` is\n // null when no priorityAttrs are configured; `finalAttrs` is null\n // when no attrs are configured. Filter null sources at the call\n // site — the `hasAnyChain` short-circuit above guarantees at least\n // one is non-null.\n const finalProps =\n prioritizedAttrs && finalAttrs\n ? mergeProps(prioritizedAttrs, finalAttrs, filteredProps)\n : prioritizedAttrs\n ? mergeProps(prioritizedAttrs, filteredProps)\n : finalAttrs\n ? mergeProps(finalAttrs, filteredProps)\n : filteredProps\n\n return WrappedComponent(finalProps)\n }\n\n return HOCComponent\n }\n\n return attrsHoc\n}\n\nexport default createAttrsHOC\n","type Func = (...args: any) => Record<string, unknown>\ntype Obj = Record<string, unknown>\n\n/**\n * Appends a new attrs option to the existing chain of option functions.\n *\n * The `.attrs()` API accepts either an object or a callback. This function\n * normalizes both forms into a function (objects are wrapped in `() => obj`)\n * and appends to the existing array. The array is cloned so each chained\n * component gets its own copy — maintaining immutability across the chain.\n */\ntype ChainOptions = (opts: Obj | Func | undefined, defaultOpts: Func[]) => Func[]\n\nexport const chainOptions: ChainOptions = (opts, defaultOpts = []) => {\n const result = [...defaultOpts]\n\n if (typeof opts === 'function') result.push(opts)\n else if (typeof opts === 'object') result.push(() => opts)\n\n return result\n}\n","/**\n * Extracts HOC functions from the `.compose()` configuration and reverses\n * them for correct application order. Setting a key to `null`, `undefined`,\n * or `false` removes a previously defined HOC — only actual functions are kept.\n *\n * The reversal is needed because `compose(a, b, c)(Component)` applies as\n * `a(b(c(Component)))`, so the last-defined HOC should wrap innermost.\n */\ntype CalculateHocsFuncs = (options: Record<string, any>) => ((arg: any) => any)[]\n\nexport const calculateHocsFuncs: CalculateHocsFuncs = (options = {}) =>\n Object.values(options)\n .filter((item) => typeof item === 'function')\n .reverse()\n","import { isEmpty } from '@pyreon/ui-core'\n\n/**\n * Copies user-defined statics from `.statics()` into the component's\n * `meta` object. These are accessible at `Component.meta.myStatic`.\n */\ntype CreateStaticsEnhancers = (params: {\n context: Record<string, any>\n options: Record<string, any>\n}) => void\n\nexport const createStaticsEnhancers: CreateStaticsEnhancers = ({ context, options }) => {\n if (!isEmpty(options)) {\n Object.assign(context, options)\n }\n}\n","import { compose, hoistNonReactStatics, omit, pick } from '@pyreon/ui-core'\nimport { attrsHoc } from './hoc'\nimport type { AttrsComponent as AttrsComponentType } from './types/AttrsComponent'\nimport type { Configuration, ExtendedConfiguration } from './types/configuration'\nimport type { InitAttrsComponent } from './types/InitAttrsComponent'\nimport { calculateChainOptions } from './utils/attrs'\nimport { chainOptions } from './utils/chaining'\nimport { calculateHocsFuncs } from './utils/compose'\nimport { createStaticsEnhancers } from './utils/statics'\n\n// Dev-mode gate. `import.meta.env.DEV` is literal-replaced by Vite at build\n// time and tree-shakes to zero bytes in prod. The previous\n// `process.env.NODE_ENV !== 'production'` form was dead code in real Vite\n// browser bundles (Vite does not polyfill `process`).\n/**\n * Clones the current configuration and merges new options, then creates a\n * fresh component. This makes the chaining API immutable — each `.attrs()`\n * / `.config()` / `.statics()` call returns a brand-new component with an\n * updated configuration rather than mutating the existing one.\n */\ntype CloneAndEnhance = (\n defaultOpts: Configuration,\n opts: Partial<ExtendedConfiguration>,\n) => ReturnType<typeof attrsComponent>\n\nconst cloneAndEnhance: CloneAndEnhance = (defaultOpts, opts) =>\n attrsComponent({\n ...defaultOpts,\n ...(opts.name ? { name: opts.name } : undefined),\n ...(opts.component ? { component: opts.component } : undefined),\n attrs: chainOptions(opts.attrs, defaultOpts.attrs),\n filterAttrs: [...(defaultOpts.filterAttrs ?? []), ...(opts.filterAttrs ?? [])],\n priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),\n statics: { ...defaultOpts.statics, ...opts.statics },\n compose: { ...defaultOpts.compose, ...opts.compose },\n } as Parameters<typeof attrsComponent>[0])\n\n/**\n * Core factory that builds an attrs-enhanced Pyreon component.\n *\n * Creates a plain ComponentFn that:\n * 1. Wraps the original with attrsHoc (default props) + user HOCs from `.compose()`.\n * 2. Filters out internal props listed in `filterAttrs`.\n * 3. Attaches `data-attrs` attribute in development for debugging.\n *\n * Then adds chaining methods (`.attrs()`, `.config()`, `.compose()`, `.statics()`)\n * as static properties — each calls `cloneAndEnhance` to produce a new component.\n *\n * In Pyreon, there is no forwardRef — ref flows as a normal prop.\n * Components are plain functions that run once per mount.\n */\nconst attrsComponent: InitAttrsComponent = (options) => {\n const componentName = options.name ?? options.component.displayName ?? options.component.name\n\n const RenderComponent = options.component\n\n // Build the HOC chain: attrsHoc is always first (resolves default props),\n // followed by user-composed HOCs in reverse order (outermost wraps first).\n const hocsFuncs = [attrsHoc(options), ...calculateHocsFuncs(options.compose)]\n\n // The inner component receives already-computed props from the HOC chain.\n // It handles prop filtering and final rendering.\n const EnhancedComponent = (props: Record<string, any>) => {\n const needsFiltering = options.filterAttrs && options.filterAttrs.length > 0\n\n const filteredProps = needsFiltering ? omit(props, options.filterAttrs) : props\n\n const finalProps = process.env.NODE_ENV !== 'production'\n ? { ...filteredProps, 'data-attrs': componentName }\n : filteredProps\n\n return RenderComponent(finalProps)\n }\n\n // Apply the full HOC chain: compose(attrsHoc, ...userHocs)(EnhancedComponent)\n const AttrsComponent: AttrsComponentType = compose(...hocsFuncs)(EnhancedComponent)\n\n AttrsComponent.IS_ATTRS = true\n AttrsComponent.displayName = componentName\n AttrsComponent.meta = {}\n\n // Copy static properties from the original component.\n hoistNonReactStatics(AttrsComponent, options.component)\n\n // Populate `component.meta` with user-defined statics from `.statics()`.\n createStaticsEnhancers({\n context: AttrsComponent.meta,\n options: options.statics,\n })\n\n // ─── Chaining Methods ──────────────────────────────────\n // Each method creates a new component via cloneAndEnhance.\n // The original component is never mutated.\n Object.assign(AttrsComponent, {\n attrs: (attrs: any, { priority, filter }: any = {}) => {\n const result: Record<string, any> = {}\n\n if (filter) {\n result.filterAttrs = filter\n }\n\n if (priority) {\n result.priorityAttrs = attrs as ExtendedConfiguration['priorityAttrs']\n\n return cloneAndEnhance(options, result)\n }\n\n result.attrs = attrs as ExtendedConfiguration['attrs']\n\n return cloneAndEnhance(options, result)\n },\n\n config: (opts: any = {}) => {\n const result = pick(opts)\n\n return cloneAndEnhance(options, result)\n },\n\n compose: (opts: any) => cloneAndEnhance(options, { compose: opts }),\n\n statics: (opts: any) => cloneAndEnhance(options, { statics: opts }),\n\n getDefaultAttrs: (props: any) => calculateChainOptions(options.attrs)([props]),\n })\n\n return AttrsComponent\n}\n\nexport default attrsComponent\n","import { isEmpty } from '@pyreon/ui-core'\nimport attrsComponent from './attrs'\nimport type { InitAttrsComponent } from './types/InitAttrsComponent'\nimport type { ElementType } from './types/utils'\n\n// Dev-mode gate. `import.meta.env.DEV` is literal-replaced by Vite at build\n// time and tree-shakes to zero bytes in prod. The previous\n// `process.env.NODE_ENV !== 'production'` form was dead code in real Vite\n// browser bundles (Vite does not polyfill `process`).\n/**\n * Public entry point for creating an attrs-enhanced component.\n *\n * ```tsx\n * const Button = attrs({ name: 'Button', component: Element })\n * .attrs({ tag: 'button' })\n * .attrs<{ primary?: boolean }>(({ primary }) => ({\n * backgroundColor: primary ? 'blue' : 'gray',\n * }))\n * ```\n */\nexport type Attrs = <C extends ElementType>({\n name,\n component,\n}: {\n name: string\n component: C\n}) => ReturnType<InitAttrsComponent<C>>\n\nconst attrs: Attrs = ({ name, component }) => {\n // Validate required params in development — fail fast with clear errors.\n if (process.env.NODE_ENV !== 'production') {\n type Errors = Partial<{\n component: string\n name: string\n }>\n\n const errors: Errors = {}\n if (!component) {\n errors.component = 'Parameter `component` is missing in params!'\n }\n\n if (!name) {\n errors.name = 'Parameter `name` is missing in params!'\n }\n\n if (!isEmpty(errors)) {\n throw Error(JSON.stringify(errors))\n }\n }\n\n // Bootstrap with empty configuration — all chains start from scratch.\n return attrsComponent({\n name,\n component,\n attrs: [],\n priorityAttrs: [],\n filterAttrs: [],\n compose: {},\n statics: {},\n })\n}\n\nexport default attrs\n","export type IsAttrsComponent = <T>(component: T) => boolean\n\n/** Runtime type guard — checks if a component was created by `attrs()`. */\nconst isAttrsComponent: IsAttrsComponent = (component) => {\n if (\n component &&\n (typeof component === 'object' || typeof component === 'function') &&\n Object.hasOwn(component as object, 'IS_ATTRS')\n ) {\n return true\n }\n\n return false\n}\n\nexport default isAttrsComponent\n","import type { Attrs } from './init'\nimport attrs from './init'\nimport type { IsAttrsComponent } from './isAttrsComponent'\nimport isAttrsComponent from './isAttrsComponent'\nimport type { AttrsComponent } from './types/AttrsComponent'\nimport type { AttrsCb } from './types/attrs'\nimport type { AttrsComponentType, ConfigAttrs } from './types/config'\nimport type { ComposeParam, GenericHoc } from './types/hoc'\nimport type { ComponentFn, ElementType, TObj } from './types/utils'\n\nexport type {\n Attrs,\n AttrsCb,\n AttrsComponent,\n AttrsComponentType,\n ComponentFn,\n ComposeParam,\n ConfigAttrs,\n ElementType,\n GenericHoc,\n IsAttrsComponent,\n TObj,\n}\n\nexport { attrs, isAttrsComponent }\nexport default attrs\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["attrsHoc"],"sources":["../src/utils/attrs.ts","../src/hoc/attrsHoc.ts","../src/utils/chaining.ts","../src/utils/compose.ts","../src/utils/statics.ts","../src/attrs.ts","../src/init.ts","../src/isAttrsComponent.ts","../src/index.ts"],"sourcesContent":["import { isEmpty } from '@pyreon/ui-core'\n\n// The reactive-prop-aware \"drop undefined, keep getter descriptors\" filter is\n// a `@pyreon/core` primitive (it operates on core's own `_rp` / `makeReactiveProps`\n// encoding). `@pyreon/attrs` and `@pyreon/rocketstyle` previously each hand-rolled\n// it, and THIS copy historically shipped as a value-copy that silently broke\n// reactive-prop forwarding for `attrs(Component)` consumers — exactly the bug a\n// single canonical home prevents. Re-exported (not renamed) so call sites keep\n// importing `removeUndefinedProps` from `../utils/attrs`.\nexport { removeUndefinedProps } from '@pyreon/core'\n\n/**\n * Reduces an array of option functions (from chained `.attrs()` calls)\n * into a single merged result. Each function is called with `args`\n * (typically the current props) and its return value is merged\n * left-to-right via Object.assign — so later `.attrs()` calls\n * override earlier ones.\n *\n * Returns a curried function: first call binds the chain, second\n * call provides the arguments and executes the reduction.\n *\n * Uses `Object.assign` (not `mergeProps`) because `.attrs()`\n * callbacks always return freshly-constructed object literals — the\n * keys flowing through here are written by the callback as plain\n * data properties (no getters). The reactivity-preservation\n * concern only applies to props flowing IN from the consumer\n * (handled by `removeUndefinedProps` + `mergeProps` from `@pyreon/core`\n * in the HOC's prop-merge step).\n */\ntype OptionFunc<A> = (...arg: A[]) => Record<string, unknown>\ntype CalculateChainOptions = <A>(\n options?: OptionFunc<A>[],\n) => (args: A[]) => ReturnType<OptionFunc<A>>\n\nexport const calculateChainOptions: CalculateChainOptions = (options) => (args) => {\n const result = {}\n if (!options || isEmpty(options)) return result\n\n return options.reduce((acc, item) => Object.assign(acc, item(...args)), {})\n}\n","import { mergeProps } from '@pyreon/core'\nimport type { Configuration } from '../types/configuration'\nimport type { ComponentFn } from '../types/utils'\nimport { calculateChainOptions, removeUndefinedProps } from '../utils/attrs'\n\nexport type AttrsStyleHOC = ({\n attrs,\n priorityAttrs,\n}: Pick<Configuration, 'attrs' | 'priorityAttrs'>) => (\n WrappedComponent: ComponentFn<any>,\n) => ComponentFn<any>\n\n/**\n * Creates the core HOC that computes default props from the `.attrs()` chain.\n *\n * This is always the outermost HOC in the compose chain, so it runs first.\n * It resolves both priority and normal attrs callbacks, then merges them\n * with the consumer's explicit props following this precedence:\n *\n * priorityAttrs < normalAttrs < explicit props (last wins)\n *\n * In Pyreon, components are plain functions — no forwardRef needed.\n * The ref flows as a normal prop through the chain.\n */\nconst createAttrsHOC: AttrsStyleHOC = ({ attrs, priorityAttrs }) => {\n // Pre-build the chain reducers once (not per render).\n const calculateAttrs = calculateChainOptions(attrs)\n const calculatePriorityAttrs = calculateChainOptions(priorityAttrs)\n // Most components never call .attrs() — short-circuit the merge work below\n // so the no-chain mount path skips 2 reducer invocations + 3 object spreads.\n // Mirrors vitus-labs's attrsHoc fast-path; React-side memoization\n // (useMemo / useStableValue) is omitted because Pyreon components run once\n // per mount, not on every render.\n const hasAttrs = (attrs?.length ?? 0) > 0\n const hasPriorityAttrs = (priorityAttrs?.length ?? 0) > 0\n const hasAnyChain = hasAttrs || hasPriorityAttrs\n\n const attrsHoc = (WrappedComponent: ComponentFn<any>) => {\n const HOCComponent: ComponentFn<any> = (props) => {\n // Strip undefined values so they don't shadow defaults from attrs callbacks.\n const filteredProps = removeUndefinedProps(props)\n\n // Fast path: no attrs configured — skip reducers + spreads entirely.\n if (!hasAnyChain) return WrappedComponent(filteredProps)\n\n // 1. Resolve priority attrs (lowest precedence defaults).\n const prioritizedAttrs = hasPriorityAttrs\n ? calculatePriorityAttrs([filteredProps])\n : null\n // 2. Resolve normal attrs — these see priority + explicit props as input.\n //\n // The argument passed INTO `.attrs()` callbacks must preserve getter\n // descriptors on filteredProps, so any callback that reads a reactive\n // prop (e.g. `(p) => ({ x: p.someSignalDrivenProp + 1 })`) reads the\n // live value, not a one-shot snapshot. Plain spread `{ …priority,\n // …filteredProps }` would fire every getter at this site — that was\n // the pre-fix shape that silently broke reactivity for direct\n // `attrs(Component)` consumers.\n const finalAttrs = hasAttrs\n ? calculateAttrs([\n prioritizedAttrs\n ? mergeProps(prioritizedAttrs, filteredProps)\n : filteredProps,\n ])\n : null\n\n // 3. Merge: priority < normal attrs < explicit props (last wins).\n // Use canonical `mergeProps` from @pyreon/core (not spread) so the\n // explicit-props level keeps any getter-shaped reactive props live\n // all the way to the wrapped component. `prioritizedAttrs` and\n // `finalAttrs` always come from freshly-constructed object literals\n // (in user `.attrs()` callbacks), so they carry no getters —\n // descriptor-copy is a no-op cost there.\n //\n // `mergeProps` does NOT accept null/undefined sources (unlike the\n // legacy `mergeDescriptors` it replaces). `prioritizedAttrs` is\n // null when no priorityAttrs are configured; `finalAttrs` is null\n // when no attrs are configured. Filter null sources at the call\n // site — the `hasAnyChain` short-circuit above guarantees at least\n // one is non-null.\n const finalProps =\n prioritizedAttrs && finalAttrs\n ? mergeProps(prioritizedAttrs, finalAttrs, filteredProps)\n : prioritizedAttrs\n ? mergeProps(prioritizedAttrs, filteredProps)\n : finalAttrs\n ? mergeProps(finalAttrs, filteredProps)\n : filteredProps\n\n return WrappedComponent(finalProps)\n }\n\n return HOCComponent\n }\n\n return attrsHoc\n}\n\nexport default createAttrsHOC\n","type Func = (...args: any) => Record<string, unknown>\ntype Obj = Record<string, unknown>\n\n/**\n * Appends a new attrs option to the existing chain of option functions.\n *\n * The `.attrs()` API accepts either an object or a callback. This function\n * normalizes both forms into a function (objects are wrapped in `() => obj`)\n * and appends to the existing array. The array is cloned so each chained\n * component gets its own copy — maintaining immutability across the chain.\n */\ntype ChainOptions = (opts: Obj | Func | undefined, defaultOpts: Func[]) => Func[]\n\nexport const chainOptions: ChainOptions = (opts, defaultOpts = []) => {\n const result = [...defaultOpts]\n\n if (typeof opts === 'function') result.push(opts)\n else if (typeof opts === 'object') result.push(() => opts)\n\n return result\n}\n","/**\n * Extracts HOC functions from the `.compose()` configuration and reverses\n * them for correct application order. Setting a key to `null`, `undefined`,\n * or `false` removes a previously defined HOC — only actual functions are kept.\n *\n * The reversal is needed because `compose(a, b, c)(Component)` applies as\n * `a(b(c(Component)))`, so the last-defined HOC should wrap innermost.\n */\ntype CalculateHocsFuncs = (options: Record<string, any>) => ((arg: any) => any)[]\n\nexport const calculateHocsFuncs: CalculateHocsFuncs = (options = {}) =>\n Object.values(options)\n .filter((item) => typeof item === 'function')\n .reverse()\n","import { isEmpty } from '@pyreon/ui-core'\n\n/**\n * Copies user-defined statics from `.statics()` into the component's\n * `meta` object. These are accessible at `Component.meta.myStatic`.\n */\ntype CreateStaticsEnhancers = (params: {\n context: Record<string, any>\n options: Record<string, any>\n}) => void\n\nexport const createStaticsEnhancers: CreateStaticsEnhancers = ({ context, options }) => {\n if (!isEmpty(options)) {\n Object.assign(context, options)\n }\n}\n","import { compose, hoistNonReactStatics, omit, pick } from '@pyreon/ui-core'\nimport { attrsHoc } from './hoc'\nimport type { AttrsComponent as AttrsComponentType } from './types/AttrsComponent'\nimport type { Configuration, ExtendedConfiguration } from './types/configuration'\nimport type { InitAttrsComponent } from './types/InitAttrsComponent'\nimport { calculateChainOptions } from './utils/attrs'\nimport { chainOptions } from './utils/chaining'\nimport { calculateHocsFuncs } from './utils/compose'\nimport { createStaticsEnhancers } from './utils/statics'\n\n// Dev-mode gate. `import.meta.env.DEV` is literal-replaced by Vite at build\n// time and tree-shakes to zero bytes in prod. The previous\n// `process.env.NODE_ENV !== 'production'` form was dead code in real Vite\n// browser bundles (Vite does not polyfill `process`).\n/**\n * Clones the current configuration and merges new options, then creates a\n * fresh component. This makes the chaining API immutable — each `.attrs()`\n * / `.config()` / `.statics()` call returns a brand-new component with an\n * updated configuration rather than mutating the existing one.\n */\ntype CloneAndEnhance = (\n defaultOpts: Configuration,\n opts: Partial<ExtendedConfiguration>,\n) => ReturnType<typeof attrsComponent>\n\nconst cloneAndEnhance: CloneAndEnhance = (defaultOpts, opts) =>\n attrsComponent({\n ...defaultOpts,\n ...(opts.name ? { name: opts.name } : undefined),\n ...(opts.component ? { component: opts.component } : undefined),\n attrs: chainOptions(opts.attrs, defaultOpts.attrs),\n filterAttrs: [...(defaultOpts.filterAttrs ?? []), ...(opts.filterAttrs ?? [])],\n priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),\n statics: { ...defaultOpts.statics, ...opts.statics },\n compose: { ...defaultOpts.compose, ...opts.compose },\n } as Parameters<typeof attrsComponent>[0])\n\n/**\n * Core factory that builds an attrs-enhanced Pyreon component.\n *\n * Creates a plain ComponentFn that:\n * 1. Wraps the original with attrsHoc (default props) + user HOCs from `.compose()`.\n * 2. Filters out internal props listed in `filterAttrs`.\n * 3. Attaches `data-attrs` attribute in development for debugging.\n *\n * Then adds chaining methods (`.attrs()`, `.config()`, `.compose()`, `.statics()`)\n * as static properties — each calls `cloneAndEnhance` to produce a new component.\n *\n * In Pyreon, there is no forwardRef — ref flows as a normal prop.\n * Components are plain functions that run once per mount.\n */\nconst attrsComponent: InitAttrsComponent = (options) => {\n const componentName = options.name ?? options.component.displayName ?? options.component.name\n\n const RenderComponent = options.component\n\n // Build the HOC chain: attrsHoc is always first (resolves default props),\n // followed by user-composed HOCs in reverse order (outermost wraps first).\n const hocsFuncs = [attrsHoc(options), ...calculateHocsFuncs(options.compose)]\n\n // The inner component receives already-computed props from the HOC chain.\n // It handles prop filtering and final rendering.\n const EnhancedComponent = (props: Record<string, any>) => {\n const needsFiltering = options.filterAttrs && options.filterAttrs.length > 0\n\n const filteredProps = needsFiltering ? omit(props, options.filterAttrs) : props\n\n const finalProps = process.env.NODE_ENV !== 'production'\n ? { ...filteredProps, 'data-attrs': componentName }\n : filteredProps\n\n return RenderComponent(finalProps)\n }\n\n // Apply the full HOC chain: compose(attrsHoc, ...userHocs)(EnhancedComponent)\n const AttrsComponent: AttrsComponentType = compose(...hocsFuncs)(EnhancedComponent)\n\n AttrsComponent.IS_ATTRS = true\n AttrsComponent.displayName = componentName\n AttrsComponent.meta = {}\n\n // Copy static properties from the original component.\n hoistNonReactStatics(AttrsComponent, options.component)\n\n // Populate `component.meta` with user-defined statics from `.statics()`.\n createStaticsEnhancers({\n context: AttrsComponent.meta,\n options: options.statics,\n })\n\n // ─── Chaining Methods ──────────────────────────────────\n // Each method creates a new component via cloneAndEnhance.\n // The original component is never mutated.\n Object.assign(AttrsComponent, {\n attrs: (attrs: any, { priority, filter }: any = {}) => {\n const result: Record<string, any> = {}\n\n if (filter) {\n result.filterAttrs = filter\n }\n\n if (priority) {\n result.priorityAttrs = attrs as ExtendedConfiguration['priorityAttrs']\n\n return cloneAndEnhance(options, result)\n }\n\n result.attrs = attrs as ExtendedConfiguration['attrs']\n\n return cloneAndEnhance(options, result)\n },\n\n config: (opts: any = {}) => {\n const result = pick(opts)\n\n return cloneAndEnhance(options, result)\n },\n\n compose: (opts: any) => cloneAndEnhance(options, { compose: opts }),\n\n statics: (opts: any) => cloneAndEnhance(options, { statics: opts }),\n\n getDefaultAttrs: (props: any) => calculateChainOptions(options.attrs)([props]),\n })\n\n return AttrsComponent\n}\n\nexport default attrsComponent\n","import { isEmpty } from '@pyreon/ui-core'\nimport attrsComponent from './attrs'\nimport type { InitAttrsComponent } from './types/InitAttrsComponent'\nimport type { ElementType } from './types/utils'\n\n// Dev-mode gate. `import.meta.env.DEV` is literal-replaced by Vite at build\n// time and tree-shakes to zero bytes in prod. The previous\n// `process.env.NODE_ENV !== 'production'` form was dead code in real Vite\n// browser bundles (Vite does not polyfill `process`).\n/**\n * Public entry point for creating an attrs-enhanced component.\n *\n * ```tsx\n * const Button = attrs({ name: 'Button', component: Element })\n * .attrs({ tag: 'button' })\n * .attrs<{ primary?: boolean }>(({ primary }) => ({\n * backgroundColor: primary ? 'blue' : 'gray',\n * }))\n * ```\n */\nexport type Attrs = <C extends ElementType>({\n name,\n component,\n}: {\n name: string\n component: C\n}) => ReturnType<InitAttrsComponent<C>>\n\nconst attrs: Attrs = ({ name, component }) => {\n // Validate required params in development — fail fast with clear errors.\n if (process.env.NODE_ENV !== 'production') {\n type Errors = Partial<{\n component: string\n name: string\n }>\n\n const errors: Errors = {}\n if (!component) {\n errors.component = 'Parameter `component` is missing in params!'\n }\n\n if (!name) {\n errors.name = 'Parameter `name` is missing in params!'\n }\n\n if (!isEmpty(errors)) {\n throw Error(JSON.stringify(errors))\n }\n }\n\n // Bootstrap with empty configuration — all chains start from scratch.\n return attrsComponent({\n name,\n component,\n attrs: [],\n priorityAttrs: [],\n filterAttrs: [],\n compose: {},\n statics: {},\n })\n}\n\nexport default attrs\n","export type IsAttrsComponent = <T>(component: T) => boolean\n\n/** Runtime type guard — checks if a component was created by `attrs()`. */\nconst isAttrsComponent: IsAttrsComponent = (component) => {\n if (\n component &&\n (typeof component === 'object' || typeof component === 'function') &&\n Object.hasOwn(component as object, 'IS_ATTRS')\n ) {\n return true\n }\n\n return false\n}\n\nexport default isAttrsComponent\n","import type { Attrs } from './init'\nimport attrs from './init'\nimport type { IsAttrsComponent } from './isAttrsComponent'\nimport isAttrsComponent from './isAttrsComponent'\nimport type { AttrsComponent } from './types/AttrsComponent'\nimport type { AttrsCb } from './types/attrs'\nimport type { AttrsComponentType, ConfigAttrs } from './types/config'\nimport type { ComposeParam, GenericHoc } from './types/hoc'\nimport type { ComponentFn, ElementType, TObj } from './types/utils'\n\nexport type {\n Attrs,\n AttrsCb,\n AttrsComponent,\n AttrsComponentType,\n ComponentFn,\n ComposeParam,\n ConfigAttrs,\n ElementType,\n GenericHoc,\n IsAttrsComponent,\n TObj,\n}\n\nexport { attrs, isAttrsComponent }\nexport default attrs\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/attrs",
3
- "version": "0.29.0",
3
+ "version": "0.32.0",
4
4
  "description": "Attrs HOC chaining for Pyreon components",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/ui-system/attrs#readme",
@@ -39,14 +39,14 @@
39
39
  "typecheck": "tsc --noEmit"
40
40
  },
41
41
  "peerDependencies": {
42
- "@pyreon/core": "^0.29.0"
42
+ "@pyreon/core": "^0.32.0"
43
43
  },
44
44
  "dependencies": {
45
- "@pyreon/ui-core": "^0.29.0"
45
+ "@pyreon/ui-core": "^0.32.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@pyreon/typescript": "^0.29.0",
49
- "@pyreon/vitest-config": "0.13.2",
48
+ "@pyreon/typescript": "^0.32.0",
49
+ "@pyreon/vitest-config": "0.13.3",
50
50
  "@vitus-labs/tools-rolldown": "^2.5.0"
51
51
  },
52
52
  "engines": {