bundling experiments (WIP)

Looking at ways to bundle custom widgets with Grist. WIP,
experimental, everything will need rewrite.
This commit is contained in:
Paul Fitzpatrick
2023-10-03 15:20:57 -04:00
parent 97a84ce6ee
commit fd1734de69
22 changed files with 734 additions and 155 deletions

View File

@@ -1,3 +1,5 @@
import sortBy = require('lodash/sortBy');
/**
* Custom widget manifest definition.
*/
@@ -8,6 +10,9 @@ export interface ICustomWidget {
name: string;
/**
* Widget unique id, probably in npm package format @gristlabs/custom-widget-name.
*
* There could be multiple versions of the same widget with the
* same id, e.g. a bundled version and an external version.
*/
widgetId: string;
/**
@@ -25,6 +30,8 @@ export interface ICustomWidget {
* a chance to apply the Grist theme.
*/
renderAfterReady?: boolean;
fromPlugin?: string;
}
/**
@@ -56,3 +63,65 @@ export function isSatisfied(current: AccessLevel, minimum: AccessLevel) {
}
return ordered(current) >= ordered(minimum);
}
export function matchWidget(widgets: ICustomWidget[], options: {
widgetId?: string,
pluginId?: string,
}): ICustomWidget|undefined {
console.log("MATCHING", {
widgets,
options,
});
const prefs = sortBy(widgets, (w) => {
return [w.widgetId !== options.widgetId,
(w.fromPlugin||'') !== options.pluginId]
});
if (prefs.length === 0) { return; }
if (options.widgetId && prefs[0].widgetId !== options.widgetId) {
return;
}
console.log("ORDERED", prefs);
console.log("MATCHED", prefs[0]);
return prefs[0];
}
export function filterWidgets(widgets: ICustomWidget[], options: {
preferPlugin?: boolean,
keepWidgetIdUnique?: boolean,
}) {
const folders = new Map<string, ICustomWidget[]>();
for (const widget of widgets) {
const widgetId = widget.widgetId;
if (!folders.has(widgetId)) { folders.set(widgetId, []); }
const widgetFolder = folders.get(widgetId)!;
widgetFolder.push(widget);
}
let finalResults: ICustomWidget[] = widgets;
if (options.preferPlugin !== undefined) {
const results = [];
const seen = new Set<string>();
for (const widget of widgets) {
const folder = folders.get(widget.widgetId)!;
if (folder.length === 1) {
results.push(widget);
continue;
}
if (seen.has(widget.widgetId)) { continue; }
seen.add(widget.widgetId);
const folderSorted = sortBy(folder, (w) => Boolean(w.fromPlugin) !== options.preferPlugin);
results.push(folderSorted[0]!);
}
finalResults = results;
}
if (options.keepWidgetIdUnique) {
const results = [];
const seen = new Set<string>();
for (const widget of widgets) {
if (seen.has(widget.widgetId)) { continue; }
seen.add(widget.widgetId);
results.push(widget);
}
finalResults = results;
}
return finalResults;
}