interface ExtensionArgs {
name: string;
}
class Extension<Args extends ExtensionArgs, AUI extends AutumnUI<any>> {
#name: Args['name'];
get name(): Args['name'] {
return this.#name;
}
#autumnUI: AUI;
get autumnUI() {
return this.#autumnUI;
}
constructor(args: Args, aUI: AUI) {
this.#name = args.name;
this.#autumnUI = aUI;
}
}
type Merge<A, B> = {
[K in keyof A | keyof B]: K extends keyof A & keyof B
? A[K] | B[K]
: K extends keyof B
? B[K]
: K extends keyof A
? A[K]
: never;
};
type AutumnUIBase = {
extensions: {};
};
type AutumnUI<AUI extends AutumnUIBase> = {
extensions: AUI['extensions'];
add: <
const AU extends AutumnUI<AutumnUIBase>,
const callBack extends (arg: AU) => Extension<ExtensionArgs, AU>,
const NewExtension extends ReturnType<callBack>,
>(
e: callBack,
) => {
extensions: Merge<AU['extensions'], Record<NewExtension['name'], NewExtension>>;
add: AutumnUI<AU>['add'];
};
};
declare const createAutumnUI: AutumnUI<{
extensions: {};
}>;
function ExtensionLoader<
const AUI extends AutumnUI<AutumnUIBase>,
const AUIC extends () => AUI,
const EARGS extends ExtensionArgs,
>(unusedAUI: AUIC, arg: EARGS): (autumnUI: AUI) => Extension<EARGS, AUI> {
return (autumnUI: AUI) => new Extension(arg, autumnUI);
}
const ext1 = ExtensionLoader(() => createAutumnUI, { name: 'ext1' });
const ext2 = ExtensionLoader(() => createAutumnUI.add(ext1), { name: 'ext2' });
//It only shows the command from ext2 and not ext1
const step1 = createAutumnUI.add(ext1).extensions.ext1;
const step2_0 = createAutumnUI.add(ext1).add(ext2).extensions.ext1; // should be avaliable here as well
const step2_1 = createAutumnUI.add(ext1).add(ext2).extensions.ext2;
interface ExtensionArgs {
name: string;
}
class Extension<Args extends ExtensionArgs, AUI extends AutumnUI<any>> {
#name: Args['name'];
get name(): Args['name'] {
return this.#name;
}
#autumnUI: AUI;
get autumnUI() {
return this.#autumnUI;
}
constructor(args: Args, aUI: AUI) {
this.#name = args.name;
this.#autumnUI = aUI;
}
}
type Merge<A, B> = {
[K in keyof A | keyof B]: K extends keyof A & keyof B
? A[K] | B[K]
: K extends keyof B
? B[K]
: K extends keyof A
? A[K]
: never;
};
type AutumnUIBase = {
extensions: {};
};
type AutumnUI<AUI extends AutumnUIBase> = {
extensions: AUI['extensions'];
add: <
const AU extends AutumnUI<AutumnUIBase>,
const callBack extends (arg: AU) => Extension<ExtensionArgs, AU>,
const NewExtension extends ReturnType<callBack>,
>(
e: callBack,
) => {
extensions: Merge<AU['extensions'], Record<NewExtension['name'], NewExtension>>;
add: AutumnUI<AU>['add'];
};
};
declare const createAutumnUI: AutumnUI<{
extensions: {};
}>;
function ExtensionLoader<
const AUI extends AutumnUI<AutumnUIBase>,
const AUIC extends () => AUI,
const EARGS extends ExtensionArgs,
>(unusedAUI: AUIC, arg: EARGS): (autumnUI: AUI) => Extension<EARGS, AUI> {
return (autumnUI: AUI) => new Extension(arg, autumnUI);
}
const ext1 = ExtensionLoader(() => createAutumnUI, { name: 'ext1' });
const ext2 = ExtensionLoader(() => createAutumnUI.add(ext1), { name: 'ext2' });
//It only shows the command from ext2 and not ext1
const step1 = createAutumnUI.add(ext1).extensions.ext1;
const step2_0 = createAutumnUI.add(ext1).add(ext2).extensions.ext1; // should be avaliable here as well
const step2_1 = createAutumnUI.add(ext1).add(ext2).extensions.ext2;