ivue 1.6.1 → 2.0.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
@@ -1,47 +1,185 @@
1
- ## ivue – Infinite Vue     [![npm](https://img.shields.io/npm/v/ivue.svg)](https://www.npmjs.com/package/ivue) [![build status](https://github.com/infinite-system/ivue/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/infinite-system/ivue/actions/workflows/ci.yml)
1
+ <p align="center">
2
+ <a href="https://ivue.dev/">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="docs_v2/public/brand-lockup-dark.png">
5
+ <img src="docs_v2/public/brand-lockup-light.png" alt="ivue — Infinite Vue" width="340">
6
+ </picture>
7
+ </a>
8
+ </p>
2
9
 
3
- ## About
10
+ <h3 align="center">Plain classes. Full reactivity.<br>Infinite scalability. One kilobyte.</h3>
4
11
 
5
- `ivue` is a TypeScript class based composable architecture for Vue 3, that unlocks infinite scalability for Vue 3 based apps. It allows you to extend regular Vue 3 in a simple and elegant way.
12
+ <p align="center">
13
+ <a href="https://www.npmjs.com/package/ivue"><img src="https://img.shields.io/npm/v/ivue.svg" alt="npm"></a>
14
+ <a href="https://github.com/infinite-system/ivue/actions/workflows/ci.yml"><img src="https://github.com/infinite-system/ivue/actions/workflows/ci.yml/badge.svg?branch=main" alt="build status"></a>
15
+ </p>
6
16
 
7
- ## Features
8
- &ndash; Simple & Elegant Architecture<br />
9
- &ndash; Extend Classes aligned with TypeScript Class design<br />
10
- &ndash; Extend Props Defaults<br />
11
- &ndash; Extend Emits<br />
12
- &ndash; Extend Slots<br />
13
- &ndash; Extend Components<br />
14
- &ndash; Improves DX by elegantly dealing with `.value` in the background<br />
15
- &ndash; Can be used both as a Store and a View Model for Components<br />
16
- &ndash; Zero dependencies except Vue 3<br />
17
+ <p align="center">
18
+ <strong>Docs: <a href="https://ivue.dev/">ivue.dev</a></strong>
19
+ </p>
17
20
 
18
- ## What is ivue?
19
- ## `ivue` is
21
+ ivue builds Vue 3 reactivity out of plain TypeScript classes. Real
22
+ inheritance, real encapsulation, real polymorphism — on ordinary objects,
23
+ with nothing paid until first access. The whole engine is **1.1kb gzipped**
24
+ with zero dependencies.
20
25
 
21
- &ndash;&nbsp; Simple like Options API<br />
22
- &ndash;&nbsp; Flexible like Composition API<br />
23
- &ndash;&nbsp; Extensible like TypeScript Class API<br />
24
- &ndash;&nbsp; Robust, Minimal, Opaque & Unobtrusive<br />
25
- &ndash;&nbsp; Pure Object Oriented Reactivity System based on Vue 3 Composition API<br />
26
- &ndash;&nbsp; 100% Vue 3 Compatible<br />
27
- &ndash;&nbsp; 100% Test Covered<br />
28
- &ndash;&nbsp; 100% Type Safe<br />
29
- &ndash;&nbsp; Production Ready<br />
30
- &ndash;&nbsp; Just <code>1.1kb</code> gzipped!<br />
31
- &ndash;&nbsp; 100% VSCode / Intellij IDE Auto-complete Intellisense<br />
26
+ - **Native class API** — `extends`, `super`, getters, setters, private
27
+ fields. Real inheritance, encapsulation and polymorphism, all reactive.
28
+ - **Zero-cost creation** instances are plain objects. A million of them
29
+ take 22 ms 6 to 132× faster than the alternatives.
30
+ - **One kilobyte** 1.1kb gzipped, zero dependencies, 100% test coverage.
31
+ Stripped to the load-bearing core — an API you can hold in your head.
32
+ - **Store or ViewModel** — the same class serves as a global store, a
33
+ component ViewModel, or a domain model. One mental model everywhere.
34
+ - **Composition API, fully compatible** — composables plug in through
35
+ `$`-getters. The entire Vue ecosystem works inside your classes.
36
+ - **TypeScript first** writable ref-getters, fully typed instances,
37
+ precise inference. The type system shaped the engine's design.
32
38
 
39
+ ## Getting started
33
40
 
41
+ ```sh
42
+ npm i ivue vue
43
+ ```
34
44
 
35
- `ivue` is a powerful tool because it fully aligns itself with JavaScript / TypeScript Class API.
45
+ ## Built for humans and AI
36
46
 
37
- `ivue` gives you a class based Composable capabilities with Inheritance and all the power of TypeScript Classes.
47
+ ivue ships with an [Operating Manual](https://ivue.dev/guide/standard)
48
+ the complete authoring standard as annotated templates, rules, and a review
49
+ checklist. It reads as documentation and works as a drop-in skill for AI
50
+ coding agents, so generated code follows the same standard your team writes:
38
51
 
39
- `ivue` mitigates the downsides of both Composition API and Options API, uses only their strengths and brings back Object Oriented Programming to allow the development of complex and scalable apps.
52
+ ```sh
53
+ npx ivue skill # installs .claude/skills/ivue/SKILL.md, version-locked
54
+ npx ivue skill --all # + Codex/Cursor/Copilot where already in use
55
+ ```
40
56
 
41
- `ivue` is fully interoperable with Composition API and does not work against, but rather with it, so you can use all of ecosystems composables seamlessly.
57
+ ### Usage
42
58
 
43
- `ivue` also offers a set of functions and utility types to make extensible & exportable props defaults, extensible emits and extensible slots possible.
59
+ ```ts
60
+ import { Reactive } from 'ivue';
61
+ import { ref } from 'vue';
44
62
 
45
- ## Full Documentation
63
+ class $Counter {
64
+ get count() {
65
+ return ref(0)
66
+ }
67
+ get double() {
68
+ return this.count.value * 2 // plain getter — derives on read
69
+ }
70
+ increment() {
71
+ this.count.value++
72
+ }
73
+ }
46
74
 
47
- See: https://infinite-system.github.io/ivue/
75
+ export namespace Counter {
76
+ export const $Class = $Counter; // raw — children `extends` this
77
+ export let Class = Reactive($Class); // reactive — you `new` this
78
+ export type Instance = typeof Class.Instance; // the unwrapping-surface type
79
+ }
80
+ ```
81
+
82
+ In a component:
83
+
84
+ ```vue
85
+ <script setup lang="ts">
86
+ import { Counter } from './Counter';
87
+
88
+ const counter = new Counter.Class();
89
+
90
+ // the state destructure — every Ref the template touches, unwrapped uniformly
91
+ const { count } = counter;
92
+ </script>
93
+
94
+ <template>
95
+ <button @click="counter.increment()">{{ count }} · double {{ counter.double }}</button>
96
+ </template>
97
+ ```
98
+
99
+ Full walkthrough: [Getting Started](https://ivue.dev/guide/getting-started).
100
+
101
+ ## Hard problems, solved together
102
+
103
+ Each of these sank earlier class-reactivity attempts. ivue ships all of them
104
+ as one coherent design:
105
+
106
+ - **Bound methods** — `this.method` is always correct, always the same reference.
107
+ - **Reactive inheritance** — deep `super.x.value` chains resolve level-safe.
108
+ - **Development parity** — the same class identity, direct binding, and engine branches in development and production.
109
+ - **Circular import immunity** — the namespace pattern resolves mutual references in any load order.
110
+ - **Writable getter types** — ref-returning getters type as writable; instances fully inferred.
111
+ - **Deterministic teardown** — `$watch` scopes per instance, `$stopEffects()` cleans up.
112
+ - **Minimal memory footprint** — derivations are shared prototype getters, not per-instance allocations.
113
+ - **Hot paths** — reads hoist to native ref speed with one line where it matters.
114
+
115
+ ## One idea, carried through
116
+
117
+ `Reactive()` transforms a class **once**. A getter returning `ref()` becomes
118
+ state: created on first touch, cached, stable forever. A plain getter stays
119
+ plain and re-derives on every read — reactive with zero allocation. Methods
120
+ bind themselves once, to the right `this`. Instances stay ordinary objects:
121
+ no proxy wraps them, no work happens at construction.
122
+
123
+ Inheritance, teardown, development parity, speed — consequences of that one move.
124
+
125
+ Composables plug straight in — the entire Vue ecosystem works inside your
126
+ classes:
127
+
128
+ ```ts
129
+ import { useMouse } from '@vueuse/core';
130
+
131
+ class $Pointer {
132
+ private get $mouse() {
133
+ return useMouse() // created once, encapsulated
134
+ }
135
+ get x() {
136
+ return this.$mouse.x
137
+ }
138
+ get y() {
139
+ return this.$mouse.y
140
+ }
141
+ }
142
+ ```
143
+
144
+ ## The numbers
145
+
146
+ Measured, not promised — method and live in-browser benchmarks in
147
+ [the docs](https://ivue.dev/guide/benchmarks).
148
+
149
+ | creating 1,000,000 instances | time | ivue is |
150
+ | --- | --- | --- |
151
+ | **ivue `new Class()`** | **21.7 ms** | the baseline |
152
+ | composable factory | 139 ms | **6.4× faster** |
153
+ | native `reactive()` | 470 ms | **22× faster** |
154
+
155
+ | memory heap at 100,000 live instances | per instance | 100k total |
156
+ | --- | --- | --- |
157
+ | **ivue class, 30 getters** | **3.7 KB** | 364 MB |
158
+ | composable, 30 closures | 8.0 KB | 781 MB |
159
+ | `reactive()`, fields + getters | 10.4 KB | 1.02 GB |
160
+ | composable, 30 computeds | 19.7 KB | 1.93 GB |
161
+
162
+ Taken all the way down: a fully reactive spreadsheet model holding
163
+ **20,000,000 live cells at 4.7 bytes each** — 8.5× below the plain-object
164
+ floor — because in ivue, everything costs proportional to what's *observed*,
165
+ nothing costs proportional to what *exists*.
166
+
167
+ ## A note on the size
168
+
169
+ The complete engine is **1.1kb gzipped**: lazy prototype transformation,
170
+ bound methods, inheritance, lifecycle ownership, and the public utilities.
171
+ Development uses that same engine without a second hot-update execution path.
172
+
173
+ > *Perfection is achieved, not when there is nothing more to add, but when
174
+ > there is nothing left to take away.* — Antoine de Saint-Exupéry
175
+
176
+ ## Documentation
177
+
178
+ Full guide, principles, live benchmarks, advanced examples (a 1,000,000-row
179
+ virtual scroller, a 20,000,000-cell flyweight grid, production-grade Quasar
180
+ field components), and the API reference:
181
+ **https://ivue.dev/**
182
+
183
+ ## License
184
+
185
+ [MIT](./LICENSE)
package/bin/ivue.mjs ADDED
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ivue CLI.
4
+ *
5
+ * npx ivue skill [--force]
6
+ *
7
+ * Installs the operating manual — the same document that renders as the
8
+ * docs' Standard page — into ./.claude/skills/ivue/SKILL.md, where Claude
9
+ * Code (and compatible agents) pick it up as a skill. The copy comes from
10
+ * the installed package, so the manual always matches the engine version
11
+ * the project actually runs.
12
+ */
13
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
14
+ import { dirname, join, resolve } from 'node:path';
15
+ import { fileURLToPath } from 'node:url';
16
+
17
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
18
+ const [command, ...flags] = process.argv.slice(2);
19
+
20
+ function fail(message) {
21
+ console.error(`ivue: ${message}`);
22
+ process.exit(1);
23
+ }
24
+
25
+ if (command !== 'skill') {
26
+ console.log(`ivue — commands:
27
+
28
+ npx ivue skill [targets] [--force]
29
+
30
+ Installs the ivue operating manual for coding agents. Targets:
31
+ (none) / --claude .claude/skills/ivue/SKILL.md
32
+ --cursor .cursor/rules/ivue.mdc
33
+ --copilot .github/instructions/ivue.instructions.md
34
+ --agents / --codex a managed section in AGENTS.md (Codex CLI,
35
+ Windsurf, Gemini CLI and others read this file)
36
+ --all Claude + every vendor whose footprint exists
37
+ (.cursor/, .github/, AGENTS.md) — creates nothing new
38
+ --force overwrites locally modified copies.`);
39
+ process.exit(command === undefined || command === 'help' ? 0 : 1);
40
+ }
41
+
42
+ const force = flags.includes('--force');
43
+ const version = JSON.parse(
44
+ readFileSync(join(packageRoot, 'package.json'), 'utf8'),
45
+ ).version;
46
+
47
+ // published packages carry skills/; the repo itself carries .claude/skills/
48
+ const sourcePath = [
49
+ join(packageRoot, 'skills', 'ivue', 'SKILL.md'),
50
+ join(packageRoot, '.claude', 'skills', 'ivue', 'SKILL.md'),
51
+ ].find(existsSync);
52
+ if (!sourcePath) fail('SKILL.md not found in the installed package.');
53
+
54
+ const skillText = readFileSync(sourcePath, 'utf8');
55
+ // the manual's body, without the Claude skill frontmatter
56
+ const skillBody = skillText.replace(/^---\n[\s\S]*?\n---\n+/, '');
57
+ const skillDescription =
58
+ /description:\s*([^\n]+)/.exec(skillText)?.[1] ??
59
+ 'The ivue operating manual.';
60
+
61
+ /** Write one target idempotently; refuse to clobber local edits sans --force. */
62
+ function install(relativePath, content, label) {
63
+ const targetPath = join(process.cwd(), relativePath);
64
+ if (existsSync(targetPath)) {
65
+ const existing = readFileSync(targetPath, 'utf8');
66
+ if (existing === content) {
67
+ console.log(`ivue: ${label} already up to date (ivue v${version}).`);
68
+ return;
69
+ }
70
+ if (!force) {
71
+ fail(
72
+ `${relativePath} exists and differs from ivue v${version}'s copy.\n` +
73
+ ' Re-run with --force to overwrite it.',
74
+ );
75
+ }
76
+ }
77
+ mkdirSync(dirname(targetPath), { recursive: true });
78
+ writeFileSync(targetPath, content);
79
+ console.log(`ivue: ${label} installed at ${relativePath} (ivue v${version}).`);
80
+ }
81
+
82
+ // Explicit flags always install (creating the folder is the point).
83
+ // --all is detect-and-equip: vendor targets only where their footprint
84
+ // already exists — it never scaffolds a tool you don't use. Claude is the
85
+ // native format and installs in every mode.
86
+ const wantAll = flags.includes('--all');
87
+ const detected = (marker) => existsSync(join(process.cwd(), marker));
88
+ const skipped = (label, marker, flag) =>
89
+ console.log(`ivue: ${label} skipped — no ${marker} here (pass ${flag} to create it).`);
90
+
91
+ const wantCursor = flags.includes('--cursor') || (wantAll && detected('.cursor'));
92
+ const wantCopilot = flags.includes('--copilot') || (wantAll && detected('.github'));
93
+ const wantAgents =
94
+ flags.includes('--agents') ||
95
+ flags.includes('--codex') || // Codex CLI reads AGENTS.md — same target
96
+ (wantAll && detected('AGENTS.md'));
97
+ const wantClaude =
98
+ wantAll ||
99
+ flags.includes('--claude') ||
100
+ (!flags.includes('--cursor') &&
101
+ !flags.includes('--copilot') &&
102
+ !flags.includes('--agents') &&
103
+ !flags.includes('--codex'));
104
+
105
+ if (wantClaude) {
106
+ install('.claude/skills/ivue/SKILL.md', skillText, 'Claude skill');
107
+ }
108
+ if (wantAll && !wantCursor) skipped('Cursor rule', '.cursor/', '--cursor');
109
+ if (wantAll && !wantCopilot) skipped('Copilot instructions', '.github/', '--copilot');
110
+ if (wantAll && !wantAgents) skipped('AGENTS.md section', 'AGENTS.md', '--agents');
111
+ if (wantCursor) {
112
+ install(
113
+ '.cursor/rules/ivue.mdc',
114
+ `---\ndescription: ${skillDescription}\nglobs:\nalwaysApply: false\n---\n\n${skillBody}`,
115
+ 'Cursor rule',
116
+ );
117
+ }
118
+ if (wantCopilot) {
119
+ install(
120
+ '.github/instructions/ivue.instructions.md',
121
+ `---\napplyTo: '**/*.{ts,tsx,vue}'\n---\n\n${skillBody}`,
122
+ 'Copilot instructions',
123
+ );
124
+ }
125
+ if (wantAgents) {
126
+ // AGENTS.md is shared and user-owned — manage only a marked section.
127
+ const startMarker = '<!-- ivue:skill:start -->';
128
+ const endMarker = '<!-- ivue:skill:end -->';
129
+ const section = `${startMarker}\n<!-- managed by \`npx ivue skill --agents\` — edits inside are overwritten -->\n\n${skillBody}\n${endMarker}`;
130
+ const agentsPath = join(process.cwd(), 'AGENTS.md');
131
+ if (existsSync(agentsPath)) {
132
+ const existing = readFileSync(agentsPath, 'utf8');
133
+ const start = existing.indexOf(startMarker);
134
+ const end = existing.indexOf(endMarker);
135
+ if (start !== -1 && end !== -1) {
136
+ const updated =
137
+ existing.slice(0, start) + section + existing.slice(end + endMarker.length);
138
+ if (updated === existing) {
139
+ console.log(`ivue: AGENTS.md section already up to date (ivue v${version}).`);
140
+ } else {
141
+ writeFileSync(agentsPath, updated);
142
+ console.log(`ivue: AGENTS.md section updated (ivue v${version}).`);
143
+ }
144
+ } else {
145
+ writeFileSync(agentsPath, existing.trimEnd() + '\n\n' + section + '\n');
146
+ console.log(`ivue: AGENTS.md section appended (ivue v${version}).`);
147
+ }
148
+ } else {
149
+ writeFileSync(agentsPath, section + '\n');
150
+ console.log(`ivue: AGENTS.md created (ivue v${version}).`);
151
+ }
152
+ }
@@ -0,0 +1,131 @@
1
+ import { watch, watchEffect, type ExtractPropTypes, type Ref } from 'vue';
2
+ /**
3
+ * Create a reactive class.
4
+ * @param targetClass The class to make reactive.
5
+ * @returns A reactive version of the class (the same class, transformed in place).
6
+ */
7
+ export declare function Reactive<C extends new (...args: any) => any>(targetClass: C): ReactiveClass<C> & {
8
+ Instance: ReactiveInstance<InstanceType<C>>;
9
+ };
10
+ /**
11
+ * Vue props interface in defineComponent() style.
12
+ */
13
+ export declare type VuePropsObject = Record<string, {
14
+ type: any;
15
+ default?: any;
16
+ required?: boolean;
17
+ }>;
18
+ /**
19
+ * Vue Props with default properties declared as existing and having values.
20
+ */
21
+ export declare type VuePropsWithDefaults<T extends VuePropsObject> = {
22
+ [K in keyof T]: {
23
+ type: T[K]['type'];
24
+ default: T[K]['default'];
25
+ required?: boolean;
26
+ };
27
+ };
28
+ /**
29
+ * Determines if the value is a JavaScript Class.
30
+ * Note that class is a class function in JavaScript.
31
+ *
32
+ * @param val Any value
33
+ * @returns boolean If it's a JavaScript Class returns true
34
+ */
35
+ export declare const isClass: (val: any) => boolean;
36
+ /**
37
+ * Creates props with defaults in defineComponent() style.
38
+ *
39
+ * Merge defaults regular object with Vue types object
40
+ * declared in defineComponent() style.
41
+ *
42
+ * This is made so that the defaults can be declared "as they are"
43
+ * without requiring objects to be function callbacks returning an object.
44
+ *
45
+ * // You don't need to wrap objects in () => ({ nest: { nest :{} } })
46
+ * // You can just delcare them normally.
47
+ * const defaults = {
48
+ * nest: {
49
+ * nest
50
+ * }
51
+ * }
52
+ *
53
+ * This function will create the Vue expected callbacks for Objects, Arrays & Classes
54
+ * but leave primitive properties and functions intact so that
55
+ * the final object is fully defineComponent() style compatible.
56
+ *
57
+ * The default cloner is the native `structuredClone` (zero-dependency, handles
58
+ * plain data, Map/Set/Date/typed arrays, circular refs). For defaults that
59
+ * contain class instances or functions — which `structuredClone` cannot clone —
60
+ * pass a `customCloner` such as lodash `cloneDeep`.
61
+ *
62
+ * @param defaults Regular object of default key -> values
63
+ * @param typedProps Props declared in defineComponent() style with type and possibly required declared, but without default
64
+ * @param customCloner Optional cloner used for object/array defaults (defaults to structuredClone)
65
+ * @returns Props declared in defineComponent() style with all properties having default property declared.
66
+ */
67
+ export declare const propsWithDefaults: <T extends VuePropsObject>(defaults: Record<string, any>, typedProps: T, customCloner?: ((val: any) => any) | undefined) => VuePropsWithDefaults<T>;
68
+ /**
69
+ * Type Utilities
70
+ */
71
+ declare type GetterKeys<T> = {
72
+ [K in keyof T]: T[K] extends (...args: any[]) => any ? never : T[K] extends undefined ? never : K;
73
+ }[keyof T];
74
+ declare type GetterReturn<T, K extends keyof T> = T[K] extends (...args: any[]) => any ? never : T[K];
75
+ declare type WritableComputedLike = Ref<any> & {
76
+ set: (...args: any[]) => any;
77
+ };
78
+ declare type IsWritableGetter<R> = R extends Ref<any> ? true : R extends WritableComputedLike ? true : false;
79
+ declare type WritableGetters<T> = {
80
+ [K in GetterKeys<T> as IsWritableGetter<GetterReturn<T, K>> extends true ? K : never]-?: T[K];
81
+ };
82
+ export declare type ReactiveInstance<T> = T & WritableGetters<T> & {
83
+ /** Register a watcher in the instance's lazy effect scope (same signature as Vue `watch`). */
84
+ $watch: typeof watch;
85
+ /** Register a watchEffect in the instance's lazy effect scope (same signature as Vue `watchEffect`). */
86
+ $watchEffect: typeof watchEffect;
87
+ /** Stop the instance's effect scope and drop cached cells. */
88
+ $stopEffects: () => void;
89
+ };
90
+ export declare type ReactiveClass<C extends new (...args: any) => any> = new (...args: ConstructorParameters<C>) => ReactiveInstance<InstanceType<C>>;
91
+ /**
92
+ * Component-authoring type utilities (types only — erased at build time).
93
+ * These complement `propsWithDefaults` for the params/defaults component
94
+ * architecture: object-declared emits, extensible slots, and precise
95
+ * handler-parameter extraction.
96
+ */
97
+ /** Any JavaScript function of any type. */
98
+ export declare type AnyFn = (...args: any[]) => any;
99
+ /** Convert Record to Union Type. */
100
+ export declare type RecordToUnion<T extends Record<string, any>> = T[keyof T];
101
+ /** Gets object T property by key K. */
102
+ export declare type ValueOf<T extends Record<any, any>, K extends keyof T> = T[K];
103
+ /** Convert Union Type to Intersection Type. */
104
+ export declare type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
105
+ /** Prefix keys of an interface T with a prefix P. */
106
+ export declare type PrefixKeys<T, P extends string | undefined = undefined> = {
107
+ [K in Extract<keyof T, string> as P extends string ? `${P}${K}` : K]: T[K];
108
+ };
109
+ /** Extracts object-declared emit validators into the emit-function interface. */
110
+ export declare type ExtractEmitTypes<T extends Record<string, any>> = UnionToIntersection<RecordToUnion<{
111
+ [K in keyof T]: (evt: K, ...args: Parameters<T[K]>) => void;
112
+ }>>;
113
+ /**
114
+ * Extract properties as all-assigned (non-optional) because every one of
115
+ * them carries a default.
116
+ */
117
+ export declare type ExtractPropDefaultTypes<O> = {
118
+ [K in keyof O]: K extends keyof ExtractPropTypes<O> ? ExtractPropTypes<O>[K] : never;
119
+ };
120
+ /**
121
+ * Extend a slots interface T with prefixed 'before--' & 'after--' slots to
122
+ * create fully extensible wrapped components.
123
+ */
124
+ export declare type ExtendSlots<T> = PrefixKeys<T, 'before--'> & T & PrefixKeys<T, 'after--'>;
125
+ /** Get function arguments Parameters<F> parameter by index K. */
126
+ export declare type FnParameter<F extends AnyFn, K extends number> = Parameters<F>[K];
127
+ /** Get interface T property K's function arguments as Parameters. */
128
+ export declare type IFnParameters<T extends Record<any, any>, K extends string> = Parameters<Required<Pick<T, K>>[K]>;
129
+ /** Get interface T property P's function parameter by index K. */
130
+ export declare type IFnParameter<T extends Record<any, any>, P extends keyof T, K extends number> = FnParameter<NonNullable<T[P]> extends AnyFn ? NonNullable<T[P]> : never, K>;
131
+ export {};
package/dist/index.d.ts CHANGED
@@ -1 +1 @@
1
- export * from './ivue';
1
+ export * from './Reactive';