@pyreon/attrs 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-present Vit Bokisch
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # @pyreon/attrs
2
+
3
+ Immutable, chainable default-props factory for Pyreon components.
4
+
5
+ Think of styled-components' `.attrs()` as a standalone, type-safe composition system. Define default props, swap base components, attach HOCs, and add metadata — all through an immutable chain where every call returns a new component.
6
+
7
+ ## Features
8
+
9
+ - **Immutable chaining** — every method returns a new component, never mutates the original
10
+ - **Props merge order** — `priorityAttrs` > `attrs` > explicit props, with full control over precedence
11
+ - **Prop filtering** — strip internal props before they reach the DOM
12
+ - **HOC composition** — named HOCs via `.compose()` with selective removal
13
+ - **Static metadata** — attach and access custom data via `.statics()` / `.meta`
14
+ - **TypeScript inference** — generics accumulate through the chain
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ bun add @pyreon/attrs
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```ts
25
+ import attrs from '@pyreon/attrs'
26
+ import { Element } from '@pyreon/elements'
27
+
28
+ const Button = attrs({ name: 'Button', component: Element })
29
+ .attrs({ tag: 'button', alignX: 'center', alignY: 'center' })
30
+
31
+ // Renders Element with tag="button", alignX="center", alignY="center"
32
+ Button({ label: 'Click me' })
33
+
34
+ // Explicit props override attrs defaults
35
+ Button({ tag: 'a', label: 'Link button' })
36
+ ```
37
+
38
+ ## API
39
+
40
+ ### attrs(options)
41
+
42
+ Creates an attrs-enhanced component.
43
+
44
+ ```ts
45
+ const Component = attrs({
46
+ name: 'ComponentName', // required — sets displayName
47
+ component: BaseComponent, // required — the Pyreon component to wrap
48
+ })
49
+ ```
50
+
51
+ ### .attrs(props | callback, options?)
52
+
53
+ Add default props. Can be called multiple times — defaults stack left-to-right.
54
+
55
+ ```ts
56
+ // Object form — static defaults
57
+ Button.attrs({ tag: 'button' })
58
+
59
+ // Callback form — computed defaults based on current props
60
+ Button.attrs((props) => ({
61
+ 'aria-label': props.label,
62
+ }))
63
+
64
+ // Priority — resolved before regular attrs, cannot be overridden by explicit props
65
+ Button.attrs({ tag: 'button' }, { priority: true })
66
+
67
+ // Filter — remove props before passing to the underlying component
68
+ Button.attrs({}, { filter: ['internalFlag', 'variant'] })
69
+ ```
70
+
71
+ **Props merge order:**
72
+
73
+ ```text
74
+ priorityAttrs (highest) → attrs → explicit props (lowest for priority, highest for regular)
75
+ ```
76
+
77
+ For regular attrs, explicit props win. For priority attrs, the priority value wins.
78
+
79
+ ### .config(options)
80
+
81
+ Reconfigure the component. Returns a new component instance.
82
+
83
+ ```ts
84
+ // Rename
85
+ Button.config({ name: 'PrimaryButton' })
86
+
87
+ // Swap the base component
88
+ Button.config({ component: AnotherComponent })
89
+
90
+ // Enable debug mode — adds data-attrs attribute in development
91
+ Button.config({ DEBUG: true })
92
+ ```
93
+
94
+ ### .compose(hocs)
95
+
96
+ Attach named Higher-Order Components. Applied in declaration order.
97
+
98
+ ```ts
99
+ const Enhanced = Button.compose({
100
+ withTheme: (Component) => (props) => Component({ ...props, themed: true }),
101
+ withTracking: trackingHoc,
102
+ })
103
+
104
+ // Remove a specific HOC from the chain
105
+ const WithoutTracking = Enhanced.compose({ withTracking: null })
106
+ ```
107
+
108
+ ### .statics(metadata)
109
+
110
+ Attach metadata accessible via the `.meta` property.
111
+
112
+ ```ts
113
+ const Button = attrs({ name: 'Button', component: Element })
114
+ .statics({ category: 'action', sizes: ['sm', 'md', 'lg'] })
115
+
116
+ Button.meta.category // => 'action'
117
+ Button.meta.sizes // => ['sm', 'md', 'lg']
118
+ ```
119
+
120
+ ### isAttrsComponent(value)
121
+
122
+ Runtime type guard.
123
+
124
+ ```ts
125
+ import { isAttrsComponent } from '@pyreon/attrs'
126
+
127
+ isAttrsComponent(Button) // => true
128
+ isAttrsComponent('div') // => false
129
+ ```
130
+
131
+ ### getDefaultAttrs()
132
+
133
+ Retrieve the computed default props for a component.
134
+
135
+ ```ts
136
+ Button.getDefaultAttrs() // => { tag: 'button', alignX: 'center', ... }
137
+ ```
138
+
139
+ ## TypeScript
140
+
141
+ Each `.attrs<P>()` call adds `P` to the component's prop types through `MergeTypes`:
142
+
143
+ ```ts
144
+ const Base = attrs({ name: 'Base', component: Element })
145
+
146
+ const Typed = Base
147
+ .attrs<{ variant: 'primary' | 'secondary' }>({ variant: 'primary' })
148
+ .attrs<{ size?: 'sm' | 'md' | 'lg' }>({})
149
+
150
+ // Typed accepts: Element props + { variant, size? }
151
+ Typed({ variant: 'secondary', size: 'lg', label: 'Hello' })
152
+ ```
153
+
154
+ Access the accumulated types via type-only properties:
155
+
156
+ ```ts
157
+ type AllProps = typeof Typed.$$types
158
+ type OriginalProps = typeof Typed.$$originTypes
159
+ type ExtendedProps = typeof Typed.$$extendedTypes
160
+ ```
161
+
162
+ ## Peer Dependencies
163
+
164
+ | Package | Version |
165
+ | ------- | ------- |
166
+ | @pyreon/core | >= 0.0.1 |
167
+ | @pyreon/ui-core | >= 0.0.1 |
168
+
169
+ ## License
170
+
171
+ MIT
package/lib/index.d.ts ADDED
@@ -0,0 +1,157 @@
1
+ import { VNode } from "@pyreon/core";
2
+
3
+ //#region src/types/attrs.d.ts
4
+ /** Callback form of `.attrs()` — receives current props and returns partial overrides. */
5
+ type AttrsCb<A> = (props: Partial<A>) => Partial<A>;
6
+ //#endregion
7
+ //#region src/types/utils.d.ts
8
+ type TObj = Record<string, unknown>;
9
+ type TFn = (...args: any) => any;
10
+ /**
11
+ * A Pyreon component function that accepts additional static properties.
12
+ * In Pyreon, components are plain functions: (props: P) => VNode | null.
13
+ */
14
+ type ComponentFn<P = any> = ((props: P) => VNode | null) & Partial<Record<string, any>>;
15
+ /**
16
+ * An element type — either a Pyreon component function or an intrinsic tag string.
17
+ */
18
+ type ElementType<T extends TObj | unknown = any> = ComponentFn<T>;
19
+ /**
20
+ * Forces TypeScript to expand/flatten a type for better IDE display.
21
+ * Short-circuits for `any` — the mapped type would turn `any` into
22
+ * `{ [x: string]: any; [x: number]: any; [x: symbol]: any }`, losing
23
+ * its identity as `any` and breaking downstream type checks.
24
+ */
25
+ type Id<T> = 0 extends 1 & T ? T : T extends infer U ? { [K in keyof U]: U[K] } : never;
26
+ /**
27
+ * Strips keys whose values are `never`, `null`, or `undefined`.
28
+ * Uses tuple wrapping `[T[P]] extends [never]` to avoid distribution
29
+ * over union types (a bare `T[P] extends never` would incorrectly
30
+ * match union members).
31
+ *
32
+ * Short-circuits for `any` — the `as` clause in mapped types loses
33
+ * index signatures, which would turn `any` into an empty type.
34
+ */
35
+ type IsAny<T> = 0 extends 1 & T ? true : false;
36
+ type ExtractNullableKeys<T> = 0 extends 1 & T ? T : { [P in keyof T as IsAny<T[P]> extends true ? P : [T[P]] extends [never] ? never : [T[P]] extends [null | undefined] ? never : P]: T[P] };
37
+ /** Merges two types: keeps all keys from L that don't exist in R, then adds all of R. */
38
+ type SpreadTwo<L, R> = Id<Pick<L, Exclude<keyof L, keyof R>> & R>;
39
+ /** Recursively spreads a tuple of types left-to-right. */
40
+ type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R] ? SpreadTwo<L, Spread<R>> : unknown;
41
+ /** Recursively checks whether any element in the tuple is `any`. */
42
+ type _HasAny<A> = A extends [infer L, ...infer R] ? (0 extends 1 & L ? true : _HasAny<R>) : false;
43
+ type MergeTypes<A extends readonly [...any]> = _HasAny<A> extends true ? any : ExtractNullableKeys<Spread<A>>;
44
+ /** Extracts the props type from a Pyreon component function. */
45
+ type ExtractProps<TComponentOrTProps> = TComponentOrTProps extends ComponentFn<infer TProps> ? TProps : TComponentOrTProps;
46
+ //#endregion
47
+ //#region src/types/config.d.ts
48
+ /** A component that has been enhanced by attrs — identified by the `IS_ATTRS` marker. */
49
+ type AttrsComponentType = ElementType & {
50
+ IS_ATTRS: true;
51
+ };
52
+ /** Parameters accepted by the `.config()` chaining method. */
53
+ type ConfigAttrs<C extends ElementType | unknown> = Partial<{
54
+ name: string;
55
+ component: C;
56
+ DEBUG: boolean;
57
+ }>;
58
+ //#endregion
59
+ //#region src/types/hoc.d.ts
60
+ type GenericHoc = (component: ElementType) => ElementType;
61
+ /**
62
+ * Parameters for `.compose()` — a record of named HOCs.
63
+ * Setting a key to `null`, `undefined`, or `false` removes a
64
+ * previously defined HOC from the chain.
65
+ */
66
+ type ComposeParam = Record<string, GenericHoc | null | undefined | false>;
67
+ //#endregion
68
+ //#region src/types/AttrsComponent.d.ts
69
+ /**
70
+ * @param OA Origin component props params.
71
+ * @param EA Extended prop types
72
+ * @param S Defined statics
73
+ * @param HOC High-order components
74
+ * @param DFP Calculated final component props
75
+ */
76
+ interface AttrsComponent<C extends ElementType = ElementType, OA extends TObj = TObj, EA extends TObj = TObj, S extends TObj = TObj, HOC extends TObj = TObj, DFP extends Record<string, any> = MergeTypes<[OA, EA]>> {
77
+ (props: DFP): VNode | null;
78
+ config: <NC extends ElementType | unknown = unknown>({
79
+ name,
80
+ component: NC,
81
+ DEBUG
82
+ }: ConfigAttrs<NC>) => NC extends ElementType ? AttrsComponent<NC, ExtractProps<NC>, EA, S, HOC> : AttrsComponent<C, OA, EA, S, HOC>;
83
+ attrs: <P extends TObj | unknown = unknown>(param: P extends TObj ? Partial<MergeTypes<[DFP, P]>> | AttrsCb<MergeTypes<[DFP, P]>> : Partial<DFP> | AttrsCb<DFP>, config?: Partial<{
84
+ priority: boolean;
85
+ filter: unknown extends P ? string[] : (keyof MergeTypes<[EA, P]>)[];
86
+ }>) => P extends TObj ? AttrsComponent<C, OA, MergeTypes<[EA, P]>, S, HOC> : AttrsComponent<C, OA, EA, S, HOC>;
87
+ compose: <P extends ComposeParam>(param: P) => P extends TObj ? AttrsComponent<C, OA, EA, S, MergeTypes<[HOC, P]>> : AttrsComponent<C, OA, EA, S, HOC>;
88
+ statics: <P extends TObj | unknown = unknown>(param: P) => P extends TObj ? AttrsComponent<C, OA, EA, MergeTypes<[S, P]>, HOC> : AttrsComponent<C, OA, EA, S, HOC>;
89
+ /** Access to all defined statics on the component. */
90
+ meta: S;
91
+ getDefaultAttrs: (props: TObj) => TObj;
92
+ readonly $$originTypes: OA;
93
+ readonly $$extendedTypes: EA;
94
+ readonly $$types: DFP;
95
+ IS_ATTRS: true;
96
+ displayName: string;
97
+ }
98
+ //#endregion
99
+ //#region src/types/configuration.d.ts
100
+ type OptionFunc = (...arg: unknown[]) => Record<string, unknown>;
101
+ type InitConfiguration<C> = {
102
+ name?: string | undefined;
103
+ component: C;
104
+ };
105
+ /**
106
+ * Internal configuration accumulated across the chaining API.
107
+ * Arrays hold the full chain — each `.attrs()` call appends to these.
108
+ */
109
+ type Configuration<C = ElementType | unknown> = InitConfiguration<C> & {
110
+ DEBUG?: boolean | undefined; /** Chain of default-props callbacks (resolved in order, later wins). */
111
+ attrs: OptionFunc[]; /** Chain of priority-props callbacks (resolved before `attrs`, can be overridden by both). */
112
+ priorityAttrs: OptionFunc[]; /** Prop names to omit before passing to the underlying component. */
113
+ filterAttrs: string[]; /** Named HOCs — set to null/false to remove from chain. */
114
+ compose: Record<string, TFn | null | undefined | false>; /** Metadata accessible via `Component.meta`. */
115
+ statics: Record<string, any>;
116
+ } & Record<string, any>;
117
+ //#endregion
118
+ //#region src/types/InitAttrsComponent.d.ts
119
+ /**
120
+ * Type of the internal `attrsComponent` factory function.
121
+ * Takes a full Configuration and returns an AttrsComponent whose
122
+ * original props (OA) are extracted from the component type C,
123
+ * with all extension slots (EA, S, HOC) starting empty.
124
+ */
125
+ type InitAttrsComponent<C extends ElementType = ElementType> = (params: Configuration<C>) => AttrsComponent<C, ExtractProps<C>, // OA — original component props
126
+ TObj, // EA — extended props (empty initially)
127
+ TObj, // S — statics (empty initially)
128
+ TObj>;
129
+ //#endregion
130
+ //#region src/init.d.ts
131
+ /**
132
+ * Public entry point for creating an attrs-enhanced component.
133
+ *
134
+ * ```tsx
135
+ * const Button = attrs({ name: 'Button', component: Element })
136
+ * .attrs({ tag: 'button' })
137
+ * .attrs<{ primary?: boolean }>(({ primary }) => ({
138
+ * backgroundColor: primary ? 'blue' : 'gray',
139
+ * }))
140
+ * ```
141
+ */
142
+ type Attrs = <C extends ElementType>({
143
+ name,
144
+ component
145
+ }: {
146
+ name: string;
147
+ component: C;
148
+ }) => ReturnType<InitAttrsComponent<C>>;
149
+ declare const attrs: Attrs;
150
+ //#endregion
151
+ //#region src/isAttrsComponent.d.ts
152
+ type IsAttrsComponent = <T>(component: T) => boolean;
153
+ /** Runtime type guard — checks if a component was created by `attrs()`. */
154
+ declare const isAttrsComponent: IsAttrsComponent;
155
+ //#endregion
156
+ export { type Attrs, type AttrsCb, type AttrsComponent, type AttrsComponentType, type ComponentFn, type ComposeParam, type ConfigAttrs, type ElementType, type GenericHoc, type IsAttrsComponent, type TObj, attrs, attrs as default, isAttrsComponent };
157
+ //# sourceMappingURL=index2.d.ts.map
package/lib/index.js ADDED
@@ -0,0 +1,177 @@
1
+ import { compose, hoistNonReactStatics, isEmpty, omit, pick } from "@pyreon/ui-core";
2
+
3
+ //#region src/utils/attrs.ts
4
+ const removeUndefinedProps = ((props) => Object.keys(props).reduce((acc, key) => {
5
+ const currentValue = props[key];
6
+ if (currentValue !== void 0) acc[key] = currentValue;
7
+ return acc;
8
+ }, {}));
9
+ const calculateChainOptions = (options) => (args) => {
10
+ const result = {};
11
+ if (!options || isEmpty(options)) return result;
12
+ return options.reduce((acc, item) => Object.assign(acc, item(...args)), {});
13
+ };
14
+
15
+ //#endregion
16
+ //#region src/hoc/attrsHoc.ts
17
+ /**
18
+ * Creates the core HOC that computes default props from the `.attrs()` chain.
19
+ *
20
+ * This is always the outermost HOC in the compose chain, so it runs first.
21
+ * It resolves both priority and normal attrs callbacks, then merges them
22
+ * with the consumer's explicit props following this precedence:
23
+ *
24
+ * priorityAttrs < normalAttrs < explicit props (last wins)
25
+ *
26
+ * In Pyreon, components are plain functions — no forwardRef needed.
27
+ * The ref flows as a normal prop through the chain.
28
+ */
29
+ const createAttrsHOC = ({ attrs, priorityAttrs }) => {
30
+ const calculateAttrs = calculateChainOptions(attrs);
31
+ const calculatePriorityAttrs = calculateChainOptions(priorityAttrs);
32
+ const attrsHoc = (WrappedComponent) => {
33
+ const HOCComponent = (props) => {
34
+ const filteredProps = removeUndefinedProps(props);
35
+ const prioritizedAttrs = calculatePriorityAttrs([filteredProps]);
36
+ const finalAttrs = calculateAttrs([{
37
+ ...prioritizedAttrs,
38
+ ...filteredProps
39
+ }]);
40
+ return WrappedComponent({
41
+ ...prioritizedAttrs,
42
+ ...finalAttrs,
43
+ ...filteredProps
44
+ });
45
+ };
46
+ return HOCComponent;
47
+ };
48
+ return attrsHoc;
49
+ };
50
+
51
+ //#endregion
52
+ //#region src/utils/chaining.ts
53
+ const chainOptions = (opts, defaultOpts = []) => {
54
+ const result = [...defaultOpts];
55
+ if (typeof opts === "function") result.push(opts);
56
+ else if (typeof opts === "object") result.push(() => opts);
57
+ return result;
58
+ };
59
+
60
+ //#endregion
61
+ //#region src/utils/compose.ts
62
+ const calculateHocsFuncs = (options = {}) => Object.values(options).filter((item) => typeof item === "function").reverse();
63
+
64
+ //#endregion
65
+ //#region src/utils/statics.ts
66
+ const createStaticsEnhancers = ({ context, options }) => {
67
+ if (!isEmpty(options)) Object.assign(context, options);
68
+ };
69
+
70
+ //#endregion
71
+ //#region src/attrs.ts
72
+ const cloneAndEnhance = (defaultOpts, opts) => attrsComponent({
73
+ ...defaultOpts,
74
+ ...opts.name ? { name: opts.name } : void 0,
75
+ ...opts.component ? { component: opts.component } : void 0,
76
+ attrs: chainOptions(opts.attrs, defaultOpts.attrs),
77
+ filterAttrs: [...defaultOpts.filterAttrs ?? [], ...opts.filterAttrs ?? []],
78
+ priorityAttrs: chainOptions(opts.priorityAttrs, defaultOpts.priorityAttrs),
79
+ statics: {
80
+ ...defaultOpts.statics,
81
+ ...opts.statics
82
+ },
83
+ compose: {
84
+ ...defaultOpts.compose,
85
+ ...opts.compose
86
+ }
87
+ });
88
+ /**
89
+ * Core factory that builds an attrs-enhanced Pyreon component.
90
+ *
91
+ * Creates a plain ComponentFn that:
92
+ * 1. Wraps the original with attrsHoc (default props) + user HOCs from `.compose()`.
93
+ * 2. Filters out internal props listed in `filterAttrs`.
94
+ * 3. Attaches `data-attrs` attribute in development for debugging.
95
+ *
96
+ * Then adds chaining methods (`.attrs()`, `.config()`, `.compose()`, `.statics()`)
97
+ * as static properties — each calls `cloneAndEnhance` to produce a new component.
98
+ *
99
+ * In Pyreon, there is no forwardRef — ref flows as a normal prop.
100
+ * Components are plain functions that run once per mount.
101
+ */
102
+ const attrsComponent = (options) => {
103
+ const componentName = options.name ?? options.component.displayName ?? options.component.name;
104
+ const RenderComponent = options.component;
105
+ const hocsFuncs = [createAttrsHOC(options), ...calculateHocsFuncs(options.compose)];
106
+ const EnhancedComponent = (props) => {
107
+ const filteredProps = options.filterAttrs && options.filterAttrs.length > 0 ? omit(props, options.filterAttrs) : props;
108
+ return RenderComponent(process.env.NODE_ENV !== "production" ? {
109
+ ...filteredProps,
110
+ "data-attrs": componentName
111
+ } : filteredProps);
112
+ };
113
+ const AttrsComponent = compose(...hocsFuncs)(EnhancedComponent);
114
+ AttrsComponent.IS_ATTRS = true;
115
+ AttrsComponent.displayName = componentName;
116
+ AttrsComponent.meta = {};
117
+ hoistNonReactStatics(AttrsComponent, options.component);
118
+ createStaticsEnhancers({
119
+ context: AttrsComponent.meta,
120
+ options: options.statics
121
+ });
122
+ Object.assign(AttrsComponent, {
123
+ attrs: (attrs, { priority, filter } = {}) => {
124
+ const result = {};
125
+ if (filter) result.filterAttrs = filter;
126
+ if (priority) {
127
+ result.priorityAttrs = attrs;
128
+ return cloneAndEnhance(options, result);
129
+ }
130
+ result.attrs = attrs;
131
+ return cloneAndEnhance(options, result);
132
+ },
133
+ config: (opts = {}) => {
134
+ return cloneAndEnhance(options, pick(opts));
135
+ },
136
+ compose: (opts) => cloneAndEnhance(options, { compose: opts }),
137
+ statics: (opts) => cloneAndEnhance(options, { statics: opts }),
138
+ getDefaultAttrs: (props) => calculateChainOptions(options.attrs)([props])
139
+ });
140
+ return AttrsComponent;
141
+ };
142
+
143
+ //#endregion
144
+ //#region src/init.ts
145
+ const attrs = ({ name, component }) => {
146
+ if (process.env.NODE_ENV !== "production") {
147
+ const errors = {};
148
+ if (!component) errors.component = "Parameter `component` is missing in params!";
149
+ if (!name) errors.name = "Parameter `name` is missing in params!";
150
+ if (!isEmpty(errors)) throw Error(JSON.stringify(errors));
151
+ }
152
+ return attrsComponent({
153
+ name,
154
+ component,
155
+ attrs: [],
156
+ priorityAttrs: [],
157
+ filterAttrs: [],
158
+ compose: {},
159
+ statics: {}
160
+ });
161
+ };
162
+
163
+ //#endregion
164
+ //#region src/isAttrsComponent.ts
165
+ /** Runtime type guard — checks if a component was created by `attrs()`. */
166
+ const isAttrsComponent = (component) => {
167
+ if (component && (typeof component === "object" || typeof component === "function") && component !== null && Object.hasOwn(component, "IS_ATTRS")) return true;
168
+ return false;
169
+ };
170
+
171
+ //#endregion
172
+ //#region src/index.ts
173
+ var src_default = attrs;
174
+
175
+ //#endregion
176
+ export { attrs, src_default as default, isAttrsComponent };
177
+ //# sourceMappingURL=index.js.map
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@pyreon/attrs",
3
+ "version": "0.0.2",
4
+ "description": "Attrs HOC chaining for Pyreon components",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "exports": {
9
+ "source": "./src/index.ts",
10
+ "import": "./lib/index.js",
11
+ "types": "./lib/index.d.ts"
12
+ },
13
+ "types": "./lib/index.d.ts",
14
+ "main": "./lib/index.js",
15
+ "files": [
16
+ "lib",
17
+ "!lib/**/*.map",
18
+ "!lib/analysis",
19
+ "README.md",
20
+ "LICENSE"
21
+ ],
22
+ "engines": {
23
+ "node": ">= 18"
24
+ },
25
+ "publishConfig": {
26
+ "access": "public"
27
+ },
28
+ "scripts": {
29
+ "prepublish": "bun run build",
30
+ "build": "bun run vl_rolldown_build",
31
+ "build:watch": "bun run vl_rolldown_build-watch",
32
+ "lint": "biome check src/",
33
+ "test": "vitest run",
34
+ "test:coverage": "vitest run --coverage",
35
+ "test:watch": "vitest",
36
+ "typecheck": "tsc --noEmit"
37
+ },
38
+ "peerDependencies": {
39
+ "@pyreon/core": ">=0.3.0",
40
+ "@pyreon/ui-core": "^0.0.2"
41
+ },
42
+ "devDependencies": {
43
+ "@vitus-labs/tools-rolldown": "^1.15.0",
44
+ "@vitus-labs/tools-typescript": "^1.15.0"
45
+ }
46
+ }