ivue 2.4.0 → 2.6.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 +1 -1
- package/bin/ivue.mjs +62 -1
- package/dist/LazyShared.d.ts +4 -4
- package/dist/Reactive.d.ts +37 -10
- package/dist/clone.d.ts +3 -0
- package/dist/extras.cjs +1 -1
- package/dist/extras.d.ts +1 -0
- package/dist/extras.es.js +1 -49
- package/dist/index.cjs +1 -1
- package/dist/index.es.js +1 -99
- package/dist/nestedProps.d.ts +67 -0
- package/lib/LazyShared.ts +4 -4
- package/lib/Reactive.ts +54 -23
- package/lib/Static.ts +30 -0
- package/lib/__tests__/Reactive.vitest.spec.ts +70 -14
- package/lib/__tests__/Static.vitest.spec.ts +60 -1
- package/lib/__tests__/ivue.vitest.spec.ts +17 -5
- package/lib/__tests__/nestedProps.vitest.spec.ts +153 -0
- package/lib/clone.ts +21 -0
- package/lib/extras.ts +1 -0
- package/lib/ivue.ts +15 -1
- package/lib/nestedProps.ts +126 -0
- package/package.json +13 -5
- package/skills/ivue/SKILL.md +334 -22
- package/skills/ivue/constitution.test.ts +143 -0
- package/skills/ivue/ivue-docs-skip.json +37 -0
- package/skills/ivue/ivue-generator-standard.ts +410 -0
- package/skills/ivue/ivue-house-gate.ts +131 -0
- package/skills/ivue/ivue-standards-check.ts +2649 -0
- package/skills/ivue/ivue-standards-skip.json +17 -0
package/README.md
CHANGED
|
@@ -189,7 +189,7 @@ export namespace TextSegmentation {
|
|
|
189
189
|
[**Invar**](https://ivue.dev/examples/invar) is ivue at full scale: a
|
|
190
190
|
complete terminal IDE — editor, workspace search, git, terminals, LSP,
|
|
191
191
|
agents — running on ivue classes under Bun, with no DOM and no Vue
|
|
192
|
-
components. **
|
|
192
|
+
components. **108,000 source lines, 384 classes, 39 invariant contracts,
|
|
193
193
|
zero import cycles**, built almost entirely by AI agents holding the
|
|
194
194
|
[Standard](https://ivue.dev/guide/standard) as their base discipline.
|
|
195
195
|
|
package/bin/ivue.mjs
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* the installed package, so the manual always matches the engine version
|
|
11
11
|
* the project actually runs.
|
|
12
12
|
*/
|
|
13
|
+
import { createHash } from 'node:crypto';
|
|
13
14
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
14
15
|
import { dirname, join, resolve } from 'node:path';
|
|
15
16
|
import { fileURLToPath } from 'node:url';
|
|
@@ -27,7 +28,11 @@ if (command !== 'skill') {
|
|
|
27
28
|
|
|
28
29
|
npx ivue skill [targets] [--force]
|
|
29
30
|
|
|
30
|
-
Installs the ivue operating manual for coding agents
|
|
31
|
+
Installs the ivue operating manual for coding agents, and (for the
|
|
32
|
+
Claude target) the house gate seed — your own extendable Standard
|
|
33
|
+
gate at .claude/skills/ivue/ivue-house-gate.ts. A house gate you have
|
|
34
|
+
customized is never overwritten; upgrade it with your AI agent using
|
|
35
|
+
the ivue skill, or --force. Targets:
|
|
31
36
|
(none) / --claude .claude/skills/ivue/SKILL.md
|
|
32
37
|
--cursor .cursor/rules/ivue.mdc
|
|
33
38
|
--copilot .github/instructions/ivue.instructions.md
|
|
@@ -58,6 +63,50 @@ const skillDescription =
|
|
|
58
63
|
/description:\s*([^\n]+)/.exec(skillText)?.[1] ??
|
|
59
64
|
'The ivue operating manual.';
|
|
60
65
|
|
|
66
|
+
/**
|
|
67
|
+
* A SEED is a file the user is meant to edit (the house gate). The install
|
|
68
|
+
* stamps it with a hash of its own content; on upgrade, a matching stamp
|
|
69
|
+
* means "untouched since install" (safe to replace), anything else means
|
|
70
|
+
* the user customized it — leave it alone and point at AI reconciliation.
|
|
71
|
+
*/
|
|
72
|
+
const SEED_STAMP = /^\/\/ ivue-seed: ([0-9a-f]{64})\n/;
|
|
73
|
+
|
|
74
|
+
function stampSeed(content) {
|
|
75
|
+
const hash = createHash('sha256').update(content).digest('hex');
|
|
76
|
+
return `// ivue-seed: ${hash}\n${content}`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function seedUntouched(existing) {
|
|
80
|
+
const stamp = SEED_STAMP.exec(existing);
|
|
81
|
+
if (!stamp) return false;
|
|
82
|
+
const body = existing.slice(stamp[0].length);
|
|
83
|
+
return createHash('sha256').update(body).digest('hex') === stamp[1];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function installSeed(relativePath, content, label) {
|
|
87
|
+
const targetPath = join(process.cwd(), relativePath);
|
|
88
|
+
const stamped = stampSeed(content);
|
|
89
|
+
if (existsSync(targetPath)) {
|
|
90
|
+
const existing = readFileSync(targetPath, 'utf8');
|
|
91
|
+
if (existing === stamped) {
|
|
92
|
+
console.log(`ivue: ${label} already up to date (ivue v${version}).`);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (!seedUntouched(existing) && !force) {
|
|
96
|
+
console.log(
|
|
97
|
+
`ivue: ${label} at ${relativePath} was customized — keeping yours.\n` +
|
|
98
|
+
' To upgrade it, ask your AI agent (with the ivue skill installed) to\n' +
|
|
99
|
+
" reconcile your gate with the new Standard's — it knows both sides.\n" +
|
|
100
|
+
' Or re-run with --force to overwrite your customizations.',
|
|
101
|
+
);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
106
|
+
writeFileSync(targetPath, stamped);
|
|
107
|
+
console.log(`ivue: ${label} installed at ${relativePath} (ivue v${version}).`);
|
|
108
|
+
}
|
|
109
|
+
|
|
61
110
|
/** Write one target idempotently; refuse to clobber local edits sans --force. */
|
|
62
111
|
function install(relativePath, content, label) {
|
|
63
112
|
const targetPath = join(process.cwd(), relativePath);
|
|
@@ -104,6 +153,18 @@ const wantClaude =
|
|
|
104
153
|
|
|
105
154
|
if (wantClaude) {
|
|
106
155
|
install('.claude/skills/ivue/SKILL.md', skillText, 'Claude skill');
|
|
156
|
+
// the house gate seed — the user's own gate, never clobbered once edited
|
|
157
|
+
const housePath = [
|
|
158
|
+
join(packageRoot, 'skills', 'ivue', 'ivue-house-gate.ts'),
|
|
159
|
+
join(packageRoot, '.claude', 'skills', 'ivue', 'ivue-house-gate.ts'),
|
|
160
|
+
].find(existsSync);
|
|
161
|
+
if (housePath) {
|
|
162
|
+
const houseSeed = readFileSync(housePath, 'utf8')
|
|
163
|
+
.replace("from '../../lib/Static'", "from 'ivue/extras'")
|
|
164
|
+
.replace("from './ivue-standards-check'", "from 'ivue/skills/ivue/ivue-standards-check'")
|
|
165
|
+
.replace("from './ivue-generator-standard'", "from 'ivue/skills/ivue/ivue-generator-standard'");
|
|
166
|
+
installSeed('.claude/skills/ivue/ivue-house-gate.ts', houseSeed, 'house gate');
|
|
167
|
+
}
|
|
107
168
|
}
|
|
108
169
|
if (wantAll && !wantCursor) skipped('Cursor rule', '.cursor/', '--cursor');
|
|
109
170
|
if (wantAll && !wantCopilot) skipped('Copilot instructions', '.github/', '--copilot');
|
package/dist/LazyShared.d.ts
CHANGED
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
* entry stays minimal.
|
|
36
36
|
*/
|
|
37
37
|
export declare class LazyShared<T> {
|
|
38
|
-
|
|
38
|
+
protected readonly make: () => T;
|
|
39
39
|
constructor(make: () => T);
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
protected constructed: boolean;
|
|
41
|
+
protected constructing: boolean;
|
|
42
|
+
protected stored: T | null;
|
|
43
43
|
get value(): T;
|
|
44
44
|
/**
|
|
45
45
|
* Drop the constructed value; the next read constructs again. For
|
package/dist/Reactive.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { watch, watchEffect, type ExtractPropTypes, type Ref } from 'vue';
|
|
2
|
+
export { clone } from './clone';
|
|
2
3
|
/**
|
|
3
4
|
* Create a reactive class.
|
|
4
5
|
* @param targetClass The class to make reactive.
|
|
@@ -54,14 +55,14 @@ export declare function isClass(val: any): boolean;
|
|
|
54
55
|
* but leave primitive properties and functions intact so that
|
|
55
56
|
* the final object is fully defineComponent() style compatible.
|
|
56
57
|
*
|
|
57
|
-
* The default cloner
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* The default cloner copies acyclic plain-object and array trees while
|
|
59
|
+
* retaining callbacks, class constructors and opaque objects by reference.
|
|
60
|
+
* For independent Map/Set/Date values or cyclic data, pass a `customCloner`
|
|
61
|
+
* such as `structuredClone` when the values support it.
|
|
61
62
|
*
|
|
62
63
|
* @param defaults Regular object of default key -> values
|
|
63
64
|
* @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
|
|
65
|
+
* @param customCloner Optional cloner used for object/array defaults (defaults to clone)
|
|
65
66
|
* @returns Props declared in defineComponent() style with all properties having default property declared.
|
|
66
67
|
*/
|
|
67
68
|
export declare function propsWithDefaults<T extends VuePropsObject>(defaults: Record<string, any>, typedProps: T, customCloner?: (val: any) => any): VuePropsWithDefaults<T>;
|
|
@@ -79,7 +80,16 @@ declare type IsWritableGetter<R> = R extends Ref<any> ? true : R extends Writabl
|
|
|
79
80
|
declare type WritableGetters<T> = {
|
|
80
81
|
[K in GetterKeys<T> as IsWritableGetter<GetterReturn<T, K>> extends true ? K : never]-?: T[K];
|
|
81
82
|
};
|
|
82
|
-
|
|
83
|
+
/**
|
|
84
|
+
* The members `Reactive()` installs on every instance's prototype. A raw
|
|
85
|
+
* class body cannot see them (the transform runs after the class is typed),
|
|
86
|
+
* so a class that calls them merges this interface into its own instance
|
|
87
|
+
* type — one declaration beside the class, zero runtime:
|
|
88
|
+
*
|
|
89
|
+
* class $Session { constructor() { this.$watch(…) } }
|
|
90
|
+
* interface $Session extends ReactiveHelpers {}
|
|
91
|
+
*/
|
|
92
|
+
export interface ReactiveHelpers {
|
|
83
93
|
/** Register a watcher in the instance's lazy effect scope (same signature as Vue `watch`). */
|
|
84
94
|
$watch: typeof watch;
|
|
85
95
|
/** Register a watchEffect in the instance's lazy effect scope (same signature as Vue `watchEffect`). */
|
|
@@ -90,7 +100,8 @@ export declare type ReactiveInstance<T> = T & WritableGetters<T> & {
|
|
|
90
100
|
$stopEffects: (options?: {
|
|
91
101
|
reset?: boolean;
|
|
92
102
|
}) => void;
|
|
93
|
-
}
|
|
103
|
+
}
|
|
104
|
+
export declare type ReactiveInstance<T> = T & WritableGetters<T> & ReactiveHelpers;
|
|
94
105
|
export declare type ReactiveClass<C extends new (...args: any) => any> = {
|
|
95
106
|
[Key in keyof C]: C[Key];
|
|
96
107
|
} & (new (...args: ConstructorParameters<C>) => ReactiveInstance<InstanceType<C>>);
|
|
@@ -118,11 +129,28 @@ export declare type ExtractEmitTypes<T extends Record<string, any>> = UnionToInt
|
|
|
118
129
|
}>>;
|
|
119
130
|
/**
|
|
120
131
|
* Extract properties as all-assigned (non-optional) because every one of
|
|
121
|
-
* them carries a default
|
|
132
|
+
* them carries a default — the honesty check: a declared type without a
|
|
133
|
+
* default is a compile error. Props declared `required: true` are FILTERED
|
|
134
|
+
* OUT automatically (a required prop can never carry a default —
|
|
135
|
+
* propsWithDefaults skips them at runtime), so no manual `Omit` is needed;
|
|
136
|
+
* a deliberately default-free OPTIONAL prop is declared `key: undefined`,
|
|
137
|
+
* stating the ruling in the defaults object itself. The `required: true`
|
|
138
|
+
* literal survives `typeof` only through generic inference — declare the
|
|
139
|
+
* types map with `definePropTypes({...})`, never as a bare object const.
|
|
122
140
|
*/
|
|
123
141
|
export declare type ExtractPropDefaultTypes<O> = {
|
|
124
|
-
[K in keyof O
|
|
142
|
+
[K in keyof O as O[K] extends {
|
|
143
|
+
required: true;
|
|
144
|
+
} ? never : K]: K extends keyof ExtractPropTypes<O> ? ExtractPropTypes<O>[K] : never;
|
|
125
145
|
};
|
|
146
|
+
/**
|
|
147
|
+
* Identity helper for a prop-TYPES map. Exists for one reason: in a bare
|
|
148
|
+
* `const propsTypes = {...}`, TypeScript widens `required: true` to
|
|
149
|
+
* `boolean`, which blinds ExtractPropDefaultTypes' required-key filter —
|
|
150
|
+
* generic inference through this call preserves the literal. Costs
|
|
151
|
+
* nothing at runtime.
|
|
152
|
+
*/
|
|
153
|
+
export declare function definePropTypes<T extends VuePropsObject>(types: T): T;
|
|
126
154
|
/**
|
|
127
155
|
* Extend a slots interface T with prefixed 'before--' & 'after--' slots to
|
|
128
156
|
* create fully extensible wrapped components.
|
|
@@ -134,4 +162,3 @@ export declare type FnParameter<F extends AnyFn, K extends number> = Parameters<
|
|
|
134
162
|
export declare type IFnParameters<T extends Record<any, any>, K extends string> = Parameters<Required<Pick<T, K>>[K]>;
|
|
135
163
|
/** Get interface T property P's function parameter by index K. */
|
|
136
164
|
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>;
|
|
137
|
-
export {};
|
package/dist/clone.d.ts
ADDED
package/dist/extras.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=Object.hasOwn,e=new Set;function o(t){if(Array.isArray(t)){const e=new Array(t.length);for(let n=0;n<t.length;n++)n in t&&(e[n]=o(t[n]));return e}if(null===t||"object"!=typeof t||t.constructor!==Object&&void 0!==t.constructor)return t;const e={__proto__:Object.getPrototypeOf(t),...t};for(const t in e)e[t]=o(e[t]);return e}function n(t){return null!==t&&"object"==typeof t&&(t.constructor===Object||void 0===t.constructor)}function r(t,e,o){for(const s in e){const c=t[s],i=e[s];void 0===c?t[s]=o(i):n(c)&&n(i)&&r(c,i,o)}}exports.LazyShared=class{constructor(t){this.make=t,this.constructed=!1,this.constructing=!1,this.stored=null}get value(){if(!this.constructed){if(this.constructing)throw new Error("LazyShared thunk cycle: this cell is read inside its own construction. Break the dependency between the two thunks.");this.constructing=!0;try{this.stored=this.make(),this.constructed=!0}finally{this.constructing=!1}}return this.stored}reset(){this.constructed=!1,this.stored=null}},exports.Static=function(o){var n;const r=class extends o{},s=new Set;for(let c=o;c!==Function.prototype;c=Object.getPrototypeOf(c))for(const o of Reflect.ownKeys(c)){if(s.has(o)||(s.add(o),"symbol"==typeof o&&null!=(n=Symbol.keyFor(o))&&n.startsWith("ivue.static"))||e.has(o))continue;const i=Object.getOwnPropertyDescriptor(c,o);if("function"==typeof i.value){const n=i.value,s="string"==typeof o?Symbol.for(`ivue.staticBound.${o}`):Symbol("ivue.staticBound");e.add(s),Object.defineProperty(r,o,{configurable:!0,enumerable:i.enumerable,get(){return t(this,s)||Object.defineProperty(this,s,{configurable:!0,value:n.bind(this)}),this[s]}})}else if(i.get&&!i.set&&"string"==typeof o&&o.startsWith("$")){const n=i.get,s=Symbol.for(`ivue.staticCache.${o}`);e.add(s),Object.defineProperty(r,o,{configurable:!0,enumerable:i.enumerable,get(){return t(this,s)||Object.defineProperty(this,s,{configurable:!0,value:n.call(this)}),this[s]}})}}return r},exports.nestedProps=function(t,e,s=o){for(const o in e){const c=t[o],i=e[o];n(c)&&n(i)&&r(c,i,s)}return t};
|
package/dist/extras.d.ts
CHANGED
package/dist/extras.es.js
CHANGED
|
@@ -1,49 +1 @@
|
|
|
1
|
-
const
|
|
2
|
-
function a(i) {
|
|
3
|
-
const n = class extends i {
|
|
4
|
-
}, c = /* @__PURE__ */ new Set();
|
|
5
|
-
for (let r = i; r !== Function.prototype; r = Object.getPrototypeOf(r))
|
|
6
|
-
for (const t of Reflect.ownKeys(r)) {
|
|
7
|
-
if (c.has(t))
|
|
8
|
-
continue;
|
|
9
|
-
c.add(t);
|
|
10
|
-
const e = Object.getOwnPropertyDescriptor(r, t);
|
|
11
|
-
if (typeof e.value == "function") {
|
|
12
|
-
const o = e.value, s = typeof t == "string" ? Symbol.for(`ivue.staticBound.${t}`) : Symbol("ivue.staticBound");
|
|
13
|
-
Object.defineProperty(n, t, { configurable: !0, enumerable: e.enumerable, get() {
|
|
14
|
-
return u(this, s) || Object.defineProperty(this, s, { configurable: !0, value: o.bind(this) }), this[s];
|
|
15
|
-
} });
|
|
16
|
-
} else if (e.get && !e.set && typeof t == "string" && t.startsWith("$")) {
|
|
17
|
-
const o = e.get, s = Symbol.for(`ivue.staticCache.${t}`);
|
|
18
|
-
Object.defineProperty(n, t, { configurable: !0, enumerable: e.enumerable, get() {
|
|
19
|
-
return u(this, s) || Object.defineProperty(this, s, { configurable: !0, value: o.call(this) }), this[s];
|
|
20
|
-
} });
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return n;
|
|
24
|
-
}
|
|
25
|
-
class h {
|
|
26
|
-
constructor(n) {
|
|
27
|
-
this.make = n, this.constructed = !1, this.constructing = !1, this.stored = null;
|
|
28
|
-
}
|
|
29
|
-
get value() {
|
|
30
|
-
if (!this.constructed) {
|
|
31
|
-
if (this.constructing)
|
|
32
|
-
throw new Error("LazyShared thunk cycle: this cell is read inside its own construction. Break the dependency between the two thunks.");
|
|
33
|
-
this.constructing = !0;
|
|
34
|
-
try {
|
|
35
|
-
this.stored = this.make(), this.constructed = !0;
|
|
36
|
-
} finally {
|
|
37
|
-
this.constructing = !1;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
return this.stored;
|
|
41
|
-
}
|
|
42
|
-
reset() {
|
|
43
|
-
this.constructed = !1, this.stored = null;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
export {
|
|
47
|
-
h as LazyShared,
|
|
48
|
-
a as Static
|
|
49
|
-
};
|
|
1
|
+
const t=Object.hasOwn,e=/* @__PURE__ */new Set;function n(n){var o;const r=class extends n{},s=/* @__PURE__ */new Set;for(let c=n;c!==Function.prototype;c=Object.getPrototypeOf(c))for(const n of Reflect.ownKeys(c)){if(s.has(n)||(s.add(n),"symbol"==typeof n&&null!=(o=Symbol.keyFor(n))&&o.startsWith("ivue.static"))||e.has(n))continue;const i=Object.getOwnPropertyDescriptor(c,n);if("function"==typeof i.value){const o=i.value,s="string"==typeof n?Symbol.for(`ivue.staticBound.${n}`):Symbol("ivue.staticBound");e.add(s),Object.defineProperty(r,n,{configurable:!0,enumerable:i.enumerable,get(){return t(this,s)||Object.defineProperty(this,s,{configurable:!0,value:o.bind(this)}),this[s]}})}else if(i.get&&!i.set&&"string"==typeof n&&n.startsWith("$")){const o=i.get,s=Symbol.for(`ivue.staticCache.${n}`);e.add(s),Object.defineProperty(r,n,{configurable:!0,enumerable:i.enumerable,get(){return t(this,s)||Object.defineProperty(this,s,{configurable:!0,value:o.call(this)}),this[s]}})}}return r}class o{constructor(t){this.make=t,this.constructed=!1,this.constructing=!1,this.stored=null}get value(){if(!this.constructed){if(this.constructing)throw new Error("LazyShared thunk cycle: this cell is read inside its own construction. Break the dependency between the two thunks.");this.constructing=!0;try{this.stored=this.make(),this.constructed=!0}finally{this.constructing=!1}}return this.stored}reset(){this.constructed=!1,this.stored=null}}function r(t){if(Array.isArray(t)){const e=new Array(t.length);for(let n=0;n<t.length;n++)n in t&&(e[n]=r(t[n]));return e}if(null===t||"object"!=typeof t||t.constructor!==Object&&void 0!==t.constructor)return t;const e={__proto__:Object.getPrototypeOf(t),...t};for(const t in e)e[t]=r(e[t]);return e}function s(t){return null!==t&&"object"==typeof t&&(t.constructor===Object||void 0===t.constructor)}function c(t,e,n){for(const o in e){const r=t[o],i=e[o];void 0===r?t[o]=n(i):s(r)&&s(i)&&c(r,i,n)}}function i(t,e,n=r){for(const o in e){const r=t[o],i=e[o];s(r)&&s(i)&&c(r,i,n)}return t}export{o as LazyShared,n as Static,i as nestedProps};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("vue");function e(t){if(Array.isArray(t)){const o=new Array(t.length);for(let n=0;n<t.length;n++)n in t&&(o[n]=e(t[n]));return o}if(null===t||"object"!=typeof t||t.constructor!==Object&&void 0!==t.constructor)return t;const o={__proto__:Object.getPrototypeOf(t),...t};for(const t in o)o[t]=e(o[t]);return o}const o=Object.hasOwn,n=Object.getPrototypeOf,r=Object.getOwnPropertyDescriptor,c=Object.getOwnPropertyNames,u=Object.defineProperty,s=Object.prototype,i=Symbol.for("ivue.raw"),f=Symbol.for("ivue.scope"),l=Symbol.for("ivue.processed");function a(e){const o=t.toRaw(e);if(o!==e)return o[i]??(o[i]=o);const n=e[i];return n?n===e?n:t.toRaw(n):e[i]=e}function p(t,e,o,n){u(t,e,{configurable:!0,enumerable:!1,get(){const t=a(this);return t[o]??(t[o]=n.bind(t))},set(t){a(this)[o]=t}})}function b(e,o,n,r,c){const s="$"===o[0];u(e,o,{configurable:!0,enumerable:!1,get:function(){const i=a(this);if(n in i)return i[n];const f=r.call(i);return s?(i[n]=f,f):(t.isRef(f)?i[n]=f:u(e,o,{configurable:!0,enumerable:!1,get(){return r.call(a(this))},set:c?function(t){return c.call(a(this),t)}:void 0}),f)},set:c?function(t){return c.call(a(this),t)}:void 0})}function y(t){var e;return!("function"!=typeof t||!t.prototype||null!=(e=r(t,"prototype"))&&e.writable)}exports.Reactive=function(e){const i=[];let y=e.prototype;for(;y&&y!==s;)i.push(y),y=n(y);i.reverse();for(const t of i){if(o(t,l))continue;const e=c(t),n=[];for(const o of e){if("constructor"===o)continue;const e=r(t,o);if("function"==typeof e.value){const r=Symbol(o);n.push(r),p(t,o,r,e.value)}else if(e.get){const r=Symbol(o);n.push(r),b(t,o,r,e.get,e.set)}}u(t,l,{value:n})}return o(e.prototype,"$stopEffects")||(u(e.prototype,"$watch",{enumerable:!1,configurable:!0,writable:!0,value:function(...e){const o=a(this);return(o[f]??(o[f]=t.effectScope(!0))).run((()=>t.watch(...e)))}}),u(e.prototype,"$watchEffect",{enumerable:!1,configurable:!0,writable:!0,value:function(...e){const o=a(this);return(o[f]??(o[f]=t.effectScope(!0))).run((()=>t.watchEffect(...e)))}}),u(e.prototype,"$stopEffects",{enumerable:!1,configurable:!0,writable:!0,value:function(t){const e=a(this);try{const t=e[f];t&&t.stop()}finally{if(delete e[f],!1!==(null==t?void 0:t.reset)){let t=n(e);for(;t&&t!==s;){const o=t[l];if(o)for(const t of o)delete e[t];t=n(t)}}}}})),e},exports.clone=e,exports.definePropTypes=function(t){return t},exports.isClass=y,exports.propsWithDefaults=function(t,o,n){const r={};for(const c in o){const u=null==t?void 0:t[c],s=o[c];r[c]={...s},!s.required&&void 0!==u&&("object"==typeof u&&null!==u?r[c].default=()=>n?n(u):e(u):y(u)?r[c].default=()=>u:r[c].default=u)}return r};
|
package/dist/index.es.js
CHANGED
|
@@ -1,99 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
const m = Object.hasOwn, b = Object.getPrototypeOf, d = Object.getOwnPropertyDescriptor, S = Object.getOwnPropertyNames, a = Object.defineProperty, v = Object.prototype, p = Symbol.for("ivue.raw"), l = Symbol.for("ivue.scope"), y = Symbol.for("ivue.processed");
|
|
3
|
-
function f(e) {
|
|
4
|
-
const c = g(e);
|
|
5
|
-
if (c !== e)
|
|
6
|
-
return c[p] ?? (c[p] = c);
|
|
7
|
-
const r = e[p];
|
|
8
|
-
return r ? r === e ? r : g(r) : e[p] = e;
|
|
9
|
-
}
|
|
10
|
-
function $(e, c, r, o) {
|
|
11
|
-
a(e, c, { configurable: !0, enumerable: !1, get() {
|
|
12
|
-
const t = f(this);
|
|
13
|
-
return t[r] ?? (t[r] = o.bind(t));
|
|
14
|
-
}, set(t) {
|
|
15
|
-
f(this)[r] = t;
|
|
16
|
-
} });
|
|
17
|
-
}
|
|
18
|
-
function E(e, c, r, o, t) {
|
|
19
|
-
const n = c[0] === "$";
|
|
20
|
-
a(e, c, { configurable: !0, enumerable: !1, get: function() {
|
|
21
|
-
const s = f(this);
|
|
22
|
-
if (r in s)
|
|
23
|
-
return s[r];
|
|
24
|
-
const u = o.call(s);
|
|
25
|
-
return n ? (s[r] = u, u) : (j(u) ? s[r] = u : a(e, c, { configurable: !0, enumerable: !1, get() {
|
|
26
|
-
return o.call(f(this));
|
|
27
|
-
}, set: t ? function(i) {
|
|
28
|
-
return t.call(f(this), i);
|
|
29
|
-
} : void 0 }), u);
|
|
30
|
-
}, set: t ? function(s) {
|
|
31
|
-
return t.call(f(this), s);
|
|
32
|
-
} : void 0 });
|
|
33
|
-
}
|
|
34
|
-
function C(e) {
|
|
35
|
-
const c = [];
|
|
36
|
-
let r = e.prototype;
|
|
37
|
-
for (; r && r !== v; )
|
|
38
|
-
c.push(r), r = b(r);
|
|
39
|
-
c.reverse();
|
|
40
|
-
for (const o of c) {
|
|
41
|
-
if (m(o, y))
|
|
42
|
-
continue;
|
|
43
|
-
const t = S(o), n = [];
|
|
44
|
-
for (const s of t) {
|
|
45
|
-
if (s === "constructor")
|
|
46
|
-
continue;
|
|
47
|
-
const u = d(o, s);
|
|
48
|
-
if (typeof u.value == "function") {
|
|
49
|
-
const i = Symbol(s);
|
|
50
|
-
n.push(i), $(o, s, i, u.value);
|
|
51
|
-
} else if (u.get) {
|
|
52
|
-
const i = Symbol(s);
|
|
53
|
-
n.push(i), E(o, s, i, u.get, u.set);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
a(o, y, { value: n });
|
|
57
|
-
}
|
|
58
|
-
return m(e.prototype, "$stopEffects") || (a(e.prototype, "$watch", { enumerable: !1, configurable: !0, writable: !0, value: function(...o) {
|
|
59
|
-
const t = f(this);
|
|
60
|
-
return (t[l] ?? (t[l] = h(!0))).run(() => w(...o));
|
|
61
|
-
} }), a(e.prototype, "$watchEffect", { enumerable: !1, configurable: !0, writable: !0, value: function(...o) {
|
|
62
|
-
const t = f(this);
|
|
63
|
-
return (t[l] ?? (t[l] = h(!0))).run(() => O(...o));
|
|
64
|
-
} }), a(e.prototype, "$stopEffects", { enumerable: !1, configurable: !0, writable: !0, value: function(o) {
|
|
65
|
-
const t = f(this);
|
|
66
|
-
try {
|
|
67
|
-
const n = t[l];
|
|
68
|
-
n && n.stop();
|
|
69
|
-
} finally {
|
|
70
|
-
if (delete t[l], (o == null ? void 0 : o.reset) !== !1) {
|
|
71
|
-
let n = b(t);
|
|
72
|
-
for (; n && n !== v; ) {
|
|
73
|
-
const s = n[y];
|
|
74
|
-
if (s)
|
|
75
|
-
for (const u of s)
|
|
76
|
-
delete t[u];
|
|
77
|
-
n = b(n);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
} })), e;
|
|
82
|
-
}
|
|
83
|
-
function P(e) {
|
|
84
|
-
var c;
|
|
85
|
-
return typeof e == "function" && !!e.prototype && !((c = d(e, "prototype")) != null && c.writable);
|
|
86
|
-
}
|
|
87
|
-
function D(e, c, r) {
|
|
88
|
-
const o = {};
|
|
89
|
-
for (const t in c) {
|
|
90
|
-
const n = e == null ? void 0 : e[t], s = c[t];
|
|
91
|
-
o[t] = { ...s }, s.required || n === void 0 || (typeof n == "object" && n !== null ? o[t].default = () => r ? r(n) : structuredClone(n) : P(n) ? o[t].default = () => n : o[t].default = n);
|
|
92
|
-
}
|
|
93
|
-
return o;
|
|
94
|
-
}
|
|
95
|
-
export {
|
|
96
|
-
C as Reactive,
|
|
97
|
-
P as isClass,
|
|
98
|
-
D as propsWithDefaults
|
|
99
|
-
};
|
|
1
|
+
import{effectScope as t,watch as e,watchEffect as o,toRaw as n,isRef as r}from"vue";function c(t){if(Array.isArray(t)){const e=new Array(t.length);for(let o=0;o<t.length;o++)o in t&&(e[o]=c(t[o]));return e}if(null===t||"object"!=typeof t||t.constructor!==Object&&void 0!==t.constructor)return t;const e={__proto__:Object.getPrototypeOf(t),...t};for(const t in e)e[t]=c(e[t]);return e}const s=Object.hasOwn,u=Object.getPrototypeOf,i=Object.getOwnPropertyDescriptor,f=Object.getOwnPropertyNames,l=Object.defineProperty,a=Object.prototype,p=Symbol.for("ivue.raw"),b=Symbol.for("ivue.scope"),y=Symbol.for("ivue.processed");function h(t){const e=n(t);if(e!==t)return e[p]??(e[p]=e);const o=t[p];return o?o===t?o:n(o):t[p]=t}function v(t,e,o,n){l(t,e,{configurable:!0,enumerable:!1,get(){const t=h(this);return t[o]??(t[o]=n.bind(t))},set(t){h(this)[o]=t}})}function g(t,e,o,n,c){const s="$"===e[0];l(t,e,{configurable:!0,enumerable:!1,get:function(){const u=h(this);if(o in u)return u[o];const i=n.call(u);return s?(u[o]=i,i):(r(i)?u[o]=i:l(t,e,{configurable:!0,enumerable:!1,get(){return n.call(h(this))},set:c?function(t){return c.call(h(this),t)}:void 0}),i)},set:c?function(t){return c.call(h(this),t)}:void 0})}function d(n){const r=[];let c=n.prototype;for(;c&&c!==a;)r.push(c),c=u(c);r.reverse();for(const t of r){if(s(t,y))continue;const e=f(t),o=[];for(const n of e){if("constructor"===n)continue;const e=i(t,n);if("function"==typeof e.value){const r=Symbol(n);o.push(r),v(t,n,r,e.value)}else if(e.get){const r=Symbol(n);o.push(r),g(t,n,r,e.get,e.set)}}l(t,y,{value:o})}return s(n.prototype,"$stopEffects")||(l(n.prototype,"$watch",{enumerable:!1,configurable:!0,writable:!0,value:function(...o){const n=h(this);return(n[b]??(n[b]=t(!0))).run((()=>e(...o)))}}),l(n.prototype,"$watchEffect",{enumerable:!1,configurable:!0,writable:!0,value:function(...e){const n=h(this);return(n[b]??(n[b]=t(!0))).run((()=>o(...e)))}}),l(n.prototype,"$stopEffects",{enumerable:!1,configurable:!0,writable:!0,value:function(t){const e=h(this);try{const t=e[b];t&&t.stop()}finally{if(delete e[b],!1!==(null==t?void 0:t.reset)){let t=u(e);for(;t&&t!==a;){const o=t[y];if(o)for(const t of o)delete e[t];t=u(t)}}}}})),n}function m(t){var e;return!("function"!=typeof t||!t.prototype||null!=(e=i(t,"prototype"))&&e.writable)}function w(t,e,o){const n={};for(const r in e){const s=null==t?void 0:t[r],u=e[r];n[r]={...u},!u.required&&void 0!==s&&("object"==typeof s&&null!==s?n[r].default=()=>o?o(s):c(s):m(s)?n[r].default=()=>s:n[r].default=s)}return n}function O(t){return t}export{d as Reactive,c as clone,O as definePropTypes,m as isClass,w as propsWithDefaults};
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `nestedProps(props, defaults)` — fill a nested object prop from its
|
|
3
|
+
* defaults, in place, so the class reads complete props at every depth.
|
|
4
|
+
*
|
|
5
|
+
* Vue resolves a prop's default only when the prop is ABSENT: pass
|
|
6
|
+
* `{ wheel: { gain: 2 } }` for a prop whose default is
|
|
7
|
+
* `{ wheel: { gain: 1, follow: 0.1 }, touch: { … } }` and the component
|
|
8
|
+
* receives exactly the object it was passed — `follow` and `touch` are
|
|
9
|
+
* gone. `propsWithDefaults` decides what the default IS and clones it per
|
|
10
|
+
* instance; it cannot reach inside a supplied object. The fill is possible
|
|
11
|
+
* at all because the defaults are a value the class owns — a compiler-only
|
|
12
|
+
* default has nothing to fill from.
|
|
13
|
+
*
|
|
14
|
+
* The semantics are lodash's `defaultsDeep` with arrays taken whole: for
|
|
15
|
+
* every prop whose value and default are both plain objects, each leaf the
|
|
16
|
+
* supplied object lacks is written into it from the default, recursively;
|
|
17
|
+
* a leaf it has is kept. Missing plain-object and array defaults are copied
|
|
18
|
+
* recursively so instances never share those mutable containers. Arrays
|
|
19
|
+
* are never merged; class instances and functions retain their identity. Vue's
|
|
20
|
+
* props proxy is shallow, so the nested objects are the parent's own and
|
|
21
|
+
* are written directly; the props object itself is untouched and returned.
|
|
22
|
+
*
|
|
23
|
+
* Call it once, at the seam where props enter the class:
|
|
24
|
+
*
|
|
25
|
+
* constructor(props: Scroller.Props, public emit: Scroller.Emits) {
|
|
26
|
+
* this.props = nestedProps(props, this.self.propsDefaults);
|
|
27
|
+
* }
|
|
28
|
+
*
|
|
29
|
+
* The parent passes a stable object: a constant inline literal (Vue hoists
|
|
30
|
+
* it), a `ref`'s value, a store field. An object built anew on every
|
|
31
|
+
* parent render is a new, unfilled object each time.
|
|
32
|
+
*
|
|
33
|
+
* `customCloner` is the same policy knob `propsWithDefaults` has: it copies
|
|
34
|
+
* each default branch written into the props. The default, `clone`, copies
|
|
35
|
+
* plain containers and keeps callbacks, constructors and opaque objects by
|
|
36
|
+
* reference, so no two instances share a mutable default. Pass
|
|
37
|
+
* `structuredClone` when `Date`, `Map` or `Set` defaults need their own
|
|
38
|
+
* copies; pass the identity, `value => value`, only when the caller owns
|
|
39
|
+
* every default it passes — a fresh tree per instance, never a shared one.
|
|
40
|
+
*
|
|
41
|
+
* `NestedPartial<T>` is the matching declaration for the prop's type — the
|
|
42
|
+
* shape an author may pass — and `NestedProps<P, D>` the type of the
|
|
43
|
+
* filled props, where every key both sides carry as an object is complete.
|
|
44
|
+
*
|
|
45
|
+
* Ships from `ivue/extras` (not the reactive core) so the primary `ivue`
|
|
46
|
+
* entry stays minimal.
|
|
47
|
+
*/
|
|
48
|
+
/** Every key optional at every plain-object depth; arrays stay whole. */
|
|
49
|
+
export declare type NestedPartial<T> = T extends readonly unknown[] ? T : T extends object ? {
|
|
50
|
+
[K in keyof T]?: NestedPartial<T[K]>;
|
|
51
|
+
} : T;
|
|
52
|
+
/** The filled props' type: a key both sides carry as a plain object is complete. */
|
|
53
|
+
export declare type NestedProps<P, D> = {
|
|
54
|
+
[K in keyof P as K extends keyof D ? K : never]-?: NestedLeaf<NonNullable<P[K]>, D[K & keyof D]>;
|
|
55
|
+
} & {
|
|
56
|
+
[K in keyof P as K extends keyof D ? never : K]: P[K];
|
|
57
|
+
};
|
|
58
|
+
/** A value the fill takes whole: not a plain container. */
|
|
59
|
+
declare type Opaque = Date | RegExp | Map<unknown, unknown> | Set<unknown> | ((...args: never[]) => unknown);
|
|
60
|
+
declare type NestedLeaf<V, D> = V extends readonly unknown[] ? V : V extends Opaque ? V : V extends object ? D extends readonly unknown[] ? V : D extends object ? NestedProps<V, D> : V : V;
|
|
61
|
+
/**
|
|
62
|
+
* Fill every nested object prop from its default, in place, and return
|
|
63
|
+
* the props typed as complete. Top-level props are Vue's to default and
|
|
64
|
+
* are never written.
|
|
65
|
+
*/
|
|
66
|
+
export declare function nestedProps<P extends object, D extends object>(props: P, defaults: D, customCloner?: (value: unknown) => unknown): NestedProps<P, D>;
|
|
67
|
+
export {};
|
package/lib/LazyShared.ts
CHANGED
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
* entry stays minimal.
|
|
36
36
|
*/
|
|
37
37
|
export class LazyShared<T> {
|
|
38
|
-
constructor(
|
|
38
|
+
constructor(protected readonly make: () => T) {}
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
protected constructed = false;
|
|
41
|
+
protected constructing = false;
|
|
42
|
+
protected stored: T | null = null;
|
|
43
43
|
|
|
44
44
|
get value(): T {
|
|
45
45
|
if (!this.constructed) {
|
package/lib/Reactive.ts
CHANGED
|
@@ -7,6 +7,9 @@ import {
|
|
|
7
7
|
type ExtractPropTypes,
|
|
8
8
|
type Ref,
|
|
9
9
|
} from 'vue';
|
|
10
|
+
import { clone } from './clone';
|
|
11
|
+
|
|
12
|
+
export { clone } from './clone';
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Constants & Helpers
|
|
@@ -363,20 +366,20 @@ export function isClass(val: any): boolean {
|
|
|
363
366
|
* but leave primitive properties and functions intact so that
|
|
364
367
|
* the final object is fully defineComponent() style compatible.
|
|
365
368
|
*
|
|
366
|
-
* The default cloner
|
|
367
|
-
*
|
|
368
|
-
*
|
|
369
|
-
*
|
|
369
|
+
* The default cloner copies acyclic plain-object and array trees while
|
|
370
|
+
* retaining callbacks, class constructors and opaque objects by reference.
|
|
371
|
+
* For independent Map/Set/Date values or cyclic data, pass a `customCloner`
|
|
372
|
+
* such as `structuredClone` when the values support it.
|
|
370
373
|
*
|
|
371
374
|
* @param defaults Regular object of default key -> values
|
|
372
375
|
* @param typedProps Props declared in defineComponent() style with type and possibly required declared, but without default
|
|
373
|
-
* @param customCloner Optional cloner used for object/array defaults (defaults to
|
|
376
|
+
* @param customCloner Optional cloner used for object/array defaults (defaults to clone)
|
|
374
377
|
* @returns Props declared in defineComponent() style with all properties having default property declared.
|
|
375
378
|
*/
|
|
376
379
|
export function propsWithDefaults<T extends VuePropsObject>(
|
|
377
380
|
defaults: Record<string, any>,
|
|
378
381
|
typedProps: T,
|
|
379
|
-
// Optional:
|
|
382
|
+
// Optional: Choose different ownership semantics for opaque objects or cycles.
|
|
380
383
|
customCloner?: (val: any) => any,
|
|
381
384
|
): VuePropsWithDefaults<T> {
|
|
382
385
|
// NON-MUTATING: descriptor objects are routinely SHARED between props
|
|
@@ -394,7 +397,7 @@ export function propsWithDefaults<T extends VuePropsObject>(
|
|
|
394
397
|
|
|
395
398
|
if (typeof def === 'object' && def !== null) {
|
|
396
399
|
result[prop].default = () =>
|
|
397
|
-
customCloner ? customCloner(def) :
|
|
400
|
+
customCloner ? customCloner(def) : clone(def);
|
|
398
401
|
} else {
|
|
399
402
|
if (isClass(def)) {
|
|
400
403
|
result[prop].default = () => def;
|
|
@@ -432,17 +435,27 @@ type WritableGetters<T> = {
|
|
|
432
435
|
]-?: T[K];
|
|
433
436
|
};
|
|
434
437
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
438
|
+
/**
|
|
439
|
+
* The members `Reactive()` installs on every instance's prototype. A raw
|
|
440
|
+
* class body cannot see them (the transform runs after the class is typed),
|
|
441
|
+
* so a class that calls them merges this interface into its own instance
|
|
442
|
+
* type — one declaration beside the class, zero runtime:
|
|
443
|
+
*
|
|
444
|
+
* class $Session { constructor() { this.$watch(…) } }
|
|
445
|
+
* interface $Session extends ReactiveHelpers {}
|
|
446
|
+
*/
|
|
447
|
+
export interface ReactiveHelpers {
|
|
448
|
+
/** Register a watcher in the instance's lazy effect scope (same signature as Vue `watch`). */
|
|
449
|
+
$watch: typeof watch;
|
|
450
|
+
/** Register a watchEffect in the instance's lazy effect scope (same signature as Vue `watchEffect`). */
|
|
451
|
+
$watchEffect: typeof watchEffect;
|
|
452
|
+
/** Stop the instance's effect scope and drop cached cells (the next
|
|
453
|
+
* touch re-materializes). `{ reset: false }` stops watchers only —
|
|
454
|
+
* every cached cell survives with its current value. */
|
|
455
|
+
$stopEffects: (options?: { reset?: boolean }) => void;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
export type ReactiveInstance<T> = T & WritableGetters<T> & ReactiveHelpers;
|
|
446
459
|
|
|
447
460
|
export type ReactiveClass<C extends new (...args: any) => any> = {
|
|
448
461
|
[Key in keyof C]: C[Key];
|
|
@@ -486,14 +499,32 @@ export type ExtractEmitTypes<T extends Record<string, any>> =
|
|
|
486
499
|
|
|
487
500
|
/**
|
|
488
501
|
* Extract properties as all-assigned (non-optional) because every one of
|
|
489
|
-
* them carries a default
|
|
502
|
+
* them carries a default — the honesty check: a declared type without a
|
|
503
|
+
* default is a compile error. Props declared `required: true` are FILTERED
|
|
504
|
+
* OUT automatically (a required prop can never carry a default —
|
|
505
|
+
* propsWithDefaults skips them at runtime), so no manual `Omit` is needed;
|
|
506
|
+
* a deliberately default-free OPTIONAL prop is declared `key: undefined`,
|
|
507
|
+
* stating the ruling in the defaults object itself. The `required: true`
|
|
508
|
+
* literal survives `typeof` only through generic inference — declare the
|
|
509
|
+
* types map with `definePropTypes({...})`, never as a bare object const.
|
|
490
510
|
*/
|
|
491
511
|
export type ExtractPropDefaultTypes<O> = {
|
|
492
|
-
[K in keyof O
|
|
493
|
-
?
|
|
494
|
-
: never;
|
|
512
|
+
[K in keyof O as O[K] extends { required: true }
|
|
513
|
+
? never
|
|
514
|
+
: K]: K extends keyof ExtractPropTypes<O> ? ExtractPropTypes<O>[K] : never;
|
|
495
515
|
};
|
|
496
516
|
|
|
517
|
+
/**
|
|
518
|
+
* Identity helper for a prop-TYPES map. Exists for one reason: in a bare
|
|
519
|
+
* `const propsTypes = {...}`, TypeScript widens `required: true` to
|
|
520
|
+
* `boolean`, which blinds ExtractPropDefaultTypes' required-key filter —
|
|
521
|
+
* generic inference through this call preserves the literal. Costs
|
|
522
|
+
* nothing at runtime.
|
|
523
|
+
*/
|
|
524
|
+
export function definePropTypes<T extends VuePropsObject>(types: T): T {
|
|
525
|
+
return types;
|
|
526
|
+
}
|
|
527
|
+
|
|
497
528
|
/**
|
|
498
529
|
* Extend a slots interface T with prefixed 'before--' & 'after--' slots to
|
|
499
530
|
* create fully extensible wrapped components.
|
|
@@ -516,4 +547,4 @@ export type IFnParameter<
|
|
|
516
547
|
T extends Record<any, any>,
|
|
517
548
|
P extends keyof T,
|
|
518
549
|
K extends number,
|
|
519
|
-
> = FnParameter<NonNullable<T[P]> extends AnyFn ? NonNullable<T[P]> : never, K>;
|
|
550
|
+
> = FnParameter<NonNullable<T[P]> extends AnyFn ? NonNullable<T[P]> : never, K>;
|