Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign plugin config interface #17

Open
Hoishin opened this issue Jan 11, 2025 · 8 comments
Open

Redesign plugin config interface #17

Hoishin opened this issue Jan 11, 2025 · 8 comments

Comments

@Hoishin
Copy link
Member

Hoishin commented Jan 11, 2025

I do not like the current plugin config structure. I'm not using this plugin because of that.

Current interface

interface PluginConfig {
    /** Use to map input files to template paths 
     * 
     * @default {
        'graphics/*.{js,ts}': './src/graphics/template.html',
        'dashboard/*.{js,ts}': './src/dashboard/template.html',
    }
    */
    inputs?: { [key: string]: string } | undefined

    /** Base directory for input-file paths
     * @default './src'
     */
    srcDir?: string | undefined
}

Problems

It has a certain assumption on project structure inside src. If src directory is structured differently, it cannot do the job as expected.

The inputs interface is implicit, you can't know if the key is template or the value is template.

You don't know how the output directory is determined. It makes plugin behavior hidden in a blackbox and hard to predict what happens, and makes the plugin implementation more complicated and harder to maintain.

New config interface

Because this is built for NodeCG, and NodeCG has a clear boundary of dashboard and graphics, there is no reason not to have a clear entry points for dashboard and graphics individually.

interface PluginConfig {
  // can be a path, glob path, or array of those
  graphics?: string | string[];
  dashboard?: string | string[];

  template?:
    | string
    | {
        graphics?: string,
        dashboard?: string
        override?: Array<{ input: string | string[], template: string }>
      };

  output?: { graphics?: string, dashboard?: string, shared?: string };
}
@Hoishin
Copy link
Member Author

Hoishin commented Jan 12, 2025

@Dan-Shields Would appreciate if you have any inputs on this

@Dan-Shields
Copy link
Member

Can you give an example of a src structure that isn't supported by the current config interface? I went through a few iterations that was aimed at allowing any kind of structure,

Also I think this loses the ability to assign a specific template to a specific single graphic/dashboard, no?

But I agree that the current config could and probably should be improved!

@Hoishin
Copy link
Member Author

Hoishin commented Jan 12, 2025

One example of unsupported structure is not having a src folder, like having source files in top level graphics dashboard. There are many other possible structure that is either impossible to support or really hard to predict what should be done in config to handle.

If we need to support templates for a specific file, template config can be changed to something like

interface PluginConfig {
  // can be a path, glob path, or array of those
  graphics?: string | string[];
  dashboard?: string | string[];

  template?: 
    | string
    | { graphics?: string, dashboard?: string }
    | Array<{ template: string, input: string | string[] }>

  output?: { graphics?: string, dashboard?: string, shared?: string };
}

it should at least not be a vague key value pair of object.

@Dan-Shields
Copy link
Member

Struggling to get my head around the new interface.

I have this config in the test bundle:

{
    inputs: {
        'graphics/special_graphic.js': './templates/special_template.html',
        'graphics/*/main.js': './templates/graphics.html',
        'dashboard/*/main.js': './templates/dashboard.html',
    },
}

Would then that become?:

{
    graphics: ['src/graphics/special_graphic.js', 'src/graphics/*/main.js'],
    dashboard: 'src/dashboard/*/main.js',

    template: [
        {
            inputs: 'src/graphics/*/main.js',
            template: 'templates/graphics.html'
        },
        {
            inputs: 'src/graphics/special_graphic.js',
            template: 'templates/special_template.html'
        },
        {
            inputs: 'src/dashboard/*/main.js',
            template: 'templates/dashboard.html'
        }
    ]
}

While the fact its longer isn't necessarily a bad thing, I'm not sure its any more understandable, and kinda has redundant bits. In fact, it would probably work with just the "template" section, no? That could work?

It's very possible the mock bundle is structured in a way no one but me actually uses, so feel free to suggest a more "standard" setup.

@Hoishin
Copy link
Member Author

Hoishin commented Jan 13, 2025

Having template alone is not enough because it is only configuring which script file should be using which template file. It does not determine output file (dashboard or graphics) by itself. It is the problem that the current config interface also has too. You need to build a implicit logic inside the plugin to determine which directory each input is output.

The graphics/dashboard and template field configure two completely independent concepts. The graphics/dashboard field defines which input files should be used and output to which directory. The template field defines which template file should be used for which input file.

In most cases, where you use only one framework, you would only have one or at most two template files with simple template config. I have not encountered a case where I need to define a special template file for a certain input, but if you need to do that special case, inevitably configuration becomes bigger and redundant.

@Hoishin
Copy link
Member Author

Hoishin commented Jan 13, 2025

To reduce redundancy, config can be structured like this. This is more consistent and easy to modify when you have to add special template on top of current setup.

{
  graphics: ['src/graphics/special_graphic.js', 'src/graphics/*/main.js'],
  dashboard: 'src/dashboard/*/main.js',

  template: {
    graphics: 'templates/graphics.html',
    dashboard: 'templates/dashboard.html',
    override: [
      {
        input: 'src/graphics/special_graphic.js',
        template: 'templates/special_template.html',
      },
    ],
  },
}

@Dan-Shields
Copy link
Member

Gonna give this one over to you @Hoishin, not sure I have any more input.

I haven't used nodecg, nevermind this plugin for a couple of years so I'll let you take it whichever direction you see fit.

@Hoishin
Copy link
Member Author

Hoishin commented Jan 25, 2025

OK! Fair enough. I've got valuable feedback from you too so it's not like you have to be an active user.
I'll wait for a little more to see if there is any more feedback from others.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants