Revert "NFE: Make it possible to override existing extension instances"

Signed-off-by: blam <ben@blam.sh>
This commit is contained in:
Ben Lambert
2024-07-18 13:07:02 +02:00
committed by blam
parent 966cca176b
commit 6b6cbdaac5
5 changed files with 115 additions and 516 deletions
+68 -146
View File
@@ -529,91 +529,9 @@ export function createExtensionKind<
TOutput extends AnyExtensionDataMap,
TConfig,
>(
options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>,
options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>,
): ExtensionKind<TOptions, TInputs, TOutput, TConfig>;
// @public (undocumented)
export interface CreateExtensionKindInstanceOptions<
TOptions,
TInputs extends AnyExtensionInputMap,
TOutput extends AnyExtensionDataMap,
TConfig,
> {
// (undocumented)
attachTo?: {
id: string;
input: string;
};
// (undocumented)
configSchema?: PortableSchema<TConfig>;
// (undocumented)
disabled?: boolean;
// (undocumented)
factory?(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
originalFactory(
context?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
options?: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
// (undocumented)
inputs?: TInputs;
// (undocumented)
name?: string;
// (undocumented)
namespace?: string;
// (undocumented)
options: TOptions;
// (undocumented)
output?: TOutput;
}
// @public (undocumented)
export interface CreateExtensionKindOptions<
TOptions,
TInputs extends AnyExtensionInputMap,
TOutput extends AnyExtensionDataMap,
TConfig,
> {
// (undocumented)
attachTo: {
id: string;
input: string;
};
// (undocumented)
configSchema?: PortableSchema<TConfig>;
// (undocumented)
disabled?: boolean;
// (undocumented)
factory(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
// (undocumented)
inputs?: TInputs;
// (undocumented)
kind: string;
// (undocumented)
name?: string;
// (undocumented)
namespace?: string;
// (undocumented)
output: TOutput;
}
// @public (undocumented)
export interface CreateExtensionOptions<
TOutput extends AnyExtensionDataMap,
@@ -630,7 +548,7 @@ export interface CreateExtensionOptions<
// (undocumented)
disabled?: boolean;
// (undocumented)
factory(options: {
factory(context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
@@ -647,51 +565,6 @@ export interface CreateExtensionOptions<
output: TOutput;
}
// @public (undocumented)
export interface CreateExtensionOverrideKindInstanceOptions<
TOptions,
TInputs extends AnyExtensionInputMap,
TOutput extends AnyExtensionDataMap,
TConfig,
> {
// (undocumented)
attachTo?: {
id: string;
input: string;
};
// (undocumented)
configSchema?: PortableSchema<TConfig>;
// (undocumented)
disabled?: boolean;
// (undocumented)
factory?(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
originalFactory(
context?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
options?: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
// (undocumented)
inputs?: TInputs;
// (undocumented)
name?: string;
// (undocumented)
namespace?: string;
// (undocumented)
options?: TOptions;
// (undocumented)
output?: TOutput;
}
// @public (undocumented)
export function createExtensionOverrides(
options: ExtensionOverridesOptions,
@@ -1064,26 +937,75 @@ export class ExtensionKind<
TOutput extends AnyExtensionDataMap,
TConfig,
>(
options: CreateExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>,
options: ExtensionKindOptions<TOptions, TInputs, TOutput, TConfig>,
): ExtensionKind<TOptions, TInputs, TOutput, TConfig>;
// (undocumented)
new(
instanceProperties: CreateExtensionKindInstanceOptions<
TOptions,
TInputs,
TOutput,
TConfig
>,
): ExtensionDefinition<TConfig> & {
override: (
overrides: CreateExtensionOverrideKindInstanceOptions<
TOptions,
TInputs,
TOutput,
TConfig
>,
) => ExtensionDefinition<TConfig>;
new(args: {
namespace?: string;
name?: string;
attachTo?: {
id: string;
input: string;
};
disabled?: boolean;
inputs?: TInputs;
output?: TOutput;
configSchema?: PortableSchema<TConfig>;
options: TOptions;
factory?(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
orignalFactory(
context?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
options?: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
}): ExtensionDefinition<TConfig>;
}
// @public (undocumented)
export interface ExtensionKindOptions<
TOptions,
TInputs extends AnyExtensionInputMap,
TOutput extends AnyExtensionDataMap,
TConfig,
> {
// (undocumented)
attachTo: {
id: string;
input: string;
};
// (undocumented)
configSchema?: PortableSchema<TConfig>;
// (undocumented)
disabled?: boolean;
// (undocumented)
factory(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
// (undocumented)
inputs?: TInputs;
// (undocumented)
kind: string;
// (undocumented)
name?: string;
// (undocumented)
namespace?: string;
// (undocumented)
output: TOutput;
}
// @public (undocumented)
@@ -91,7 +91,7 @@ export interface CreateExtensionOptions<
inputs?: TInputs;
output: TOutput;
configSchema?: PortableSchema<TConfig>;
factory(options: {
factory(context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
@@ -115,7 +115,7 @@ export interface InternalExtensionDefinition<TConfig>
readonly version: 'v1';
readonly inputs: AnyExtensionInputMap;
readonly output: AnyExtensionDataMap;
factory(options: {
factory(context: {
node: AppNode;
config: TConfig;
inputs: ResolvedExtensionInputs<any>;
@@ -64,7 +64,6 @@ describe('createExtensionKind', () => {
},
factory: expect.any(Function),
toString: expect.any(Function),
override: expect.any(Function),
version: 'v1',
});
@@ -103,167 +102,4 @@ describe('createExtensionKind', () => {
const { container } = createExtensionTester(extension).render();
expect(container.querySelector('h2')).toHaveTextContent('Hello, world!');
});
it('should allow calling of the default value from override', () => {
const TestExtension = createExtensionKind({
kind: 'test-extension',
attachTo: { id: 'test', input: 'default' },
output: {
element: coreExtensionData.reactElement,
},
factory(_, options: { text: string }) {
return {
element: <h1>{options.text}</h1>,
};
},
});
const extension = TestExtension.new({
name: 'my-extension',
options: {
text: 'Hello, world!',
},
factory({ originalFactory }, options: { text: string }) {
const { element } = originalFactory();
return {
element: (
<h2>
{options.text}
{element}
</h2>
),
};
},
});
expect(extension).toBeDefined();
const { container } = createExtensionTester(extension).render();
expect(container.querySelector('h2 h1')).toHaveTextContent('Hello, world!');
});
it('should allow overriding options of the default value from override', () => {
const TestExtension = createExtensionKind({
kind: 'test-extension',
attachTo: { id: 'test', input: 'default' },
output: {
element: coreExtensionData.reactElement,
},
factory(_, options: { text: string }) {
return {
element: <h1>{options.text}</h1>,
};
},
});
const extension = TestExtension.new({
name: 'my-extension',
options: {
text: 'Hello, world!',
},
factory({ originalFactory }, options: { text: string }) {
const { element } = originalFactory(undefined, { text: 'nothing!' });
return {
element: (
<h2>
{options.text}
{element}
</h2>
),
};
},
});
expect(extension).toBeDefined();
const { container } = createExtensionTester(extension).render();
expect(container.querySelector('h2 h1')).toHaveTextContent('nothing!');
});
describe('override', () => {
it('should allow overriding of the default factory', () => {
const TestExtension = createExtensionKind({
kind: 'test-extension',
attachTo: { id: 'test', input: 'default' },
output: {
element: coreExtensionData.reactElement,
},
factory(_, options: { text: string }) {
return {
element: <h1>{options.text}</h1>,
};
},
});
const extension = TestExtension.new({
name: 'my-extension',
options: {
text: 'Hello, world!',
},
factory(_, options: { text: string }) {
return {
element: <h2>{options.text}</h2>,
};
},
});
const overridden = extension.override({
factory({ originalFactory }, { text }) {
return {
element: (
<div>
{originalFactory().element}
<h3>{text}</h3>
</div>
),
};
},
});
const { container } = createExtensionTester(overridden).render();
expect(container.querySelector('h2')).toHaveTextContent('Hello, world!');
expect(container.querySelector('h3')).toHaveTextContent('Hello, world!');
});
});
it('should allow calling the kind factory if another factory is not defined in the instance', () => {
const TestExtension = createExtensionKind({
kind: 'test-extension',
attachTo: { id: 'test', input: 'default' },
output: {
element: coreExtensionData.reactElement,
},
factory(_, options: { text: string }) {
return {
element: <h1>{options.text}</h1>,
};
},
});
const extension = TestExtension.new({
name: 'my-extension',
options: {
text: 'Hello, world!',
},
});
const overridden = extension.override({
factory({ originalFactory }, { text }) {
return {
element: (
<div>
{originalFactory().element}
<h3>{text}</h3>
</div>
),
};
},
});
const { container } = createExtensionTester(overridden).render();
expect(container.querySelector('h1')).toHaveTextContent('Hello, world!');
expect(container.querySelector('h3')).toHaveTextContent('Hello, world!');
});
});
@@ -21,7 +21,6 @@ import {
AnyExtensionDataMap,
AnyExtensionInputMap,
ExtensionDataValues,
ExtensionDefinition,
ResolvedExtensionInputs,
createExtension,
} from './createExtension';
@@ -53,76 +52,6 @@ export interface CreateExtensionKindOptions<
): Expand<ExtensionDataValues<TOutput>>;
}
/**
* @public
*/
export interface CreateExtensionKindInstanceOptions<
TOptions,
TInputs extends AnyExtensionInputMap,
TOutput extends AnyExtensionDataMap,
TConfig,
> {
namespace?: string;
name?: string;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TInputs;
output?: TOutput;
configSchema?: PortableSchema<TConfig>;
options: TOptions;
factory?(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
originalFactory(
context?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
options?: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
}
/**
* @public
*/
export interface CreateExtensionOverrideKindInstanceOptions<
TOptions,
TInputs extends AnyExtensionInputMap,
TOutput extends AnyExtensionDataMap,
TConfig,
> {
namespace?: string;
name?: string;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TInputs;
output?: TOutput;
configSchema?: PortableSchema<TConfig>;
options?: TOptions;
factory?(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
originalFactory(
context?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
options?: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
}
/**
* TODO: should we export an interface instead of a concrete class?
* @public
@@ -145,7 +74,7 @@ export class ExtensionKind<
}
private constructor(
private readonly kindProperties: CreateExtensionKindOptions<
private readonly options: CreateExtensionKindOptions<
TOptions,
TInputs,
TOutput,
@@ -153,41 +82,49 @@ export class ExtensionKind<
>,
) {}
public new(
instanceProperties: CreateExtensionKindInstanceOptions<
TOptions,
TInputs,
TOutput,
TConfig
>,
): ExtensionDefinition<TConfig> & {
override: (
overrides: CreateExtensionOverrideKindInstanceOptions<
TOptions,
TInputs,
TOutput,
TConfig
>,
) => ExtensionDefinition<TConfig>;
} {
const extension = createExtension({
kind: this.kindProperties.kind,
namespace: instanceProperties.namespace ?? this.kindProperties.namespace,
name: instanceProperties.name ?? this.kindProperties.name,
attachTo: instanceProperties.attachTo ?? this.kindProperties.attachTo,
disabled: instanceProperties.disabled ?? this.kindProperties.disabled,
inputs: instanceProperties.inputs ?? this.kindProperties.inputs,
output: instanceProperties.output ?? this.kindProperties.output,
configSchema:
instanceProperties.configSchema ?? this.kindProperties.configSchema, // TODO: some config merging or smth
public new(args: {
namespace?: string;
name?: string;
attachTo?: { id: string; input: string };
disabled?: boolean;
inputs?: TInputs;
output?: TOutput;
configSchema?: PortableSchema<TConfig>;
options: TOptions;
factory?(
context: {
node: AppNode;
config: TConfig;
inputs: Expand<ResolvedExtensionInputs<TInputs>>;
orignalFactory(
context?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
options?: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
},
options: TOptions,
): Expand<ExtensionDataValues<TOutput>>;
}) {
return createExtension({
kind: this.options.kind,
namespace: args.namespace ?? this.options.namespace,
name: args.name ?? this.options.name,
attachTo: args.attachTo ?? this.options.attachTo,
disabled: args.disabled ?? this.options.disabled,
inputs: args.inputs ?? this.options.inputs,
output: args.output ?? this.options.output,
configSchema: args.configSchema ?? this.options.configSchema, // TODO: some config merging or smth
factory: ({ node, config, inputs }) => {
if (instanceProperties.factory) {
return instanceProperties.factory(
if (args.factory) {
return args.factory(
{
node,
config,
inputs,
originalFactory: (
orignalFactory: (
innerContext?: {
node?: AppNode;
config?: TConfig;
@@ -195,123 +132,29 @@ export class ExtensionKind<
},
innerOptions?: TOptions,
) =>
this.kindProperties.factory(
this.options.factory(
{
node: innerContext?.node ?? node,
config: innerContext?.config ?? config,
inputs: innerContext?.inputs ?? inputs,
},
innerOptions ?? instanceProperties.options,
innerOptions ?? args.options,
),
},
instanceProperties.options,
args.options,
);
}
return this.kindProperties.factory(
return this.options.factory(
{
node,
config,
inputs,
},
instanceProperties.options,
args.options,
);
},
});
return {
...extension,
override: overrides => {
return createExtension({
kind: this.kindProperties.kind,
namespace:
overrides.namespace ??
instanceProperties.namespace ??
this.kindProperties.namespace,
name:
overrides.name ??
instanceProperties.name ??
this.kindProperties.name,
attachTo:
overrides.attachTo ??
instanceProperties.attachTo ??
this.kindProperties.attachTo,
disabled:
overrides.disabled ??
instanceProperties.disabled ??
this.kindProperties.disabled,
inputs:
overrides.inputs ??
instanceProperties.inputs ??
this.kindProperties.inputs,
output:
overrides.output ??
instanceProperties.output ??
this.kindProperties.output,
configSchema:
overrides.configSchema ??
instanceProperties.configSchema ??
this.kindProperties.configSchema, // TODO: some config merging or smth
factory: ({ node, config, inputs }) => {
if (overrides.factory) {
return overrides.factory(
{
node,
config,
inputs,
originalFactory: (
innerContext?: {
node?: AppNode;
config?: TConfig;
inputs?: Expand<ResolvedExtensionInputs<TInputs>>;
},
innerOptions?: TOptions,
) =>
instanceProperties.factory?.(
{
node: innerContext?.node ?? node,
config: innerContext?.config ?? config,
inputs: innerContext?.inputs ?? inputs,
originalFactory: this.kindProperties.factory,
},
innerOptions ?? instanceProperties.options,
) ??
this.kindProperties.factory(
{
node,
config,
inputs,
},
innerOptions ?? instanceProperties.options,
),
},
instanceProperties.options,
);
}
return (
instanceProperties.factory?.(
{
node,
config,
inputs,
originalFactory: this.kindProperties.factory,
},
instanceProperties.options,
) ??
this.kindProperties.factory(
{
node,
config,
inputs,
},
instanceProperties.options,
)
);
},
});
},
};
}
}
@@ -49,9 +49,7 @@ export {
type FrontendFeature,
} from './types';
export {
type CreateExtensionKindOptions,
type CreateExtensionKindInstanceOptions,
type CreateExtensionOverrideKindInstanceOptions,
type CreateExtensionKindOptions as ExtensionKindOptions,
ExtensionKind,
createExtensionKind,
} from './createExtensionKind';