forked from mystiq/hydrogen-web
Do not store all the manifests in memory
This commit is contained in:
parent
b29287c47e
commit
dece42dce3
2 changed files with 16 additions and 15 deletions
|
@ -15,29 +15,26 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
import type {ThemeInformation} from "./ThemeLoader";
|
import type {ThemeInformation} from "./ThemeLoader";
|
||||||
import type {Platform} from "./Platform.js";
|
import type {Platform} from "./Platform.js";
|
||||||
|
import type {ThemeManifest} from "../types/theme";
|
||||||
import {ColorSchemePreference} from "./ThemeLoader";
|
import {ColorSchemePreference} from "./ThemeLoader";
|
||||||
import {IconColorizer} from "./IconColorizer";
|
import {IconColorizer} from "./IconColorizer";
|
||||||
import {DerivedVariables} from "./DerivedVariables";
|
import {DerivedVariables} from "./DerivedVariables";
|
||||||
import {ThemeManifest} from "../types/theme";
|
|
||||||
import {ILogItem} from "../../logging/types";
|
import {ILogItem} from "../../logging/types";
|
||||||
|
|
||||||
export class ThemeBuilder {
|
export class ThemeBuilder {
|
||||||
private _idToManifest: Map<string, {manifest: ThemeManifest, location: string}>;
|
|
||||||
private _themeMapping: Record<string, ThemeInformation> = {};
|
private _themeMapping: Record<string, ThemeInformation> = {};
|
||||||
private _preferredColorScheme?: ColorSchemePreference;
|
private _preferredColorScheme?: ColorSchemePreference;
|
||||||
private _platform: Platform;
|
private _platform: Platform;
|
||||||
private _injectedVariables?: Record<string, string>;
|
private _injectedVariables?: Record<string, string>;
|
||||||
|
|
||||||
constructor(platform: Platform, manifestMap: Map<string, any>, preferredColorScheme?: ColorSchemePreference) {
|
constructor(platform: Platform, preferredColorScheme?: ColorSchemePreference) {
|
||||||
this._idToManifest = manifestMap;
|
|
||||||
this._preferredColorScheme = preferredColorScheme;
|
this._preferredColorScheme = preferredColorScheme;
|
||||||
this._platform = platform;
|
this._platform = platform;
|
||||||
}
|
}
|
||||||
|
|
||||||
async populateDerivedTheme(manifest: ThemeManifest, log: ILogItem): Promise<void> {
|
async populateDerivedTheme(manifest: ThemeManifest, baseManifest: ThemeManifest, baseManifestLocation: string, log: ILogItem): Promise<void> {
|
||||||
await log.wrap("ThemeBuilder.populateThemeMap", async () => {
|
await log.wrap("ThemeBuilder.populateThemeMap", async () => {
|
||||||
const {manifest: baseManifest, location} = this._idToManifest.get(manifest.extends!)!;
|
const {cssLocation, derivedVariables, icons} = this._getSourceData(baseManifest, baseManifestLocation, log);
|
||||||
const {cssLocation, derivedVariables, icons} = this._getSourceData(baseManifest, location, log);
|
|
||||||
const themeName = manifest.name;
|
const themeName = manifest.name;
|
||||||
if (!themeName) {
|
if (!themeName) {
|
||||||
throw new Error(`Theme name not found in manifest!`);
|
throw new Error(`Theme name not found in manifest!`);
|
||||||
|
@ -49,7 +46,7 @@ export class ThemeBuilder {
|
||||||
const { name: variantName, default: isDefault, dark, variables } = variantDetails;
|
const { name: variantName, default: isDefault, dark, variables } = variantDetails;
|
||||||
const resolvedVariables = new DerivedVariables(variables, derivedVariables, dark).toVariables();
|
const resolvedVariables = new DerivedVariables(variables, derivedVariables, dark).toVariables();
|
||||||
Object.assign(variables, resolvedVariables);
|
Object.assign(variables, resolvedVariables);
|
||||||
const iconVariables = await new IconColorizer(this._platform, icons, variables, location).toVariables();
|
const iconVariables = await new IconColorizer(this._platform, icons, variables, baseManifestLocation).toVariables();
|
||||||
Object.assign(variables, resolvedVariables, iconVariables);
|
Object.assign(variables, resolvedVariables, iconVariables);
|
||||||
const themeDisplayName = `${themeName} ${variantName}`;
|
const themeDisplayName = `${themeName} ${variantName}`;
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {ILogItem} from "../../logging/types";
|
import type {ILogItem} from "../../logging/types";
|
||||||
import { ThemeManifest } from "../types/theme";
|
import type {ThemeManifest} from "../types/theme";
|
||||||
import type {Platform} from "./Platform.js";
|
import type {Platform} from "./Platform.js";
|
||||||
import {ThemeBuilder} from "./ThemeBuilder";
|
import {ThemeBuilder} from "./ThemeBuilder";
|
||||||
|
|
||||||
|
@ -52,20 +52,24 @@ export class ThemeLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
async init(manifestLocations: string[], log?: ILogItem): Promise<void> {
|
async init(manifestLocations: string[], log?: ILogItem): Promise<void> {
|
||||||
const idToManifest = new Map();
|
|
||||||
await this._platform.logger.wrapOrRun(log, "ThemeLoader.init", async (log) => {
|
await this._platform.logger.wrapOrRun(log, "ThemeLoader.init", async (log) => {
|
||||||
this._themeMapping = {};
|
this._themeMapping = {};
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
manifestLocations.map( location => this._platform.request(location, { method: "GET", format: "json", cache: true, }).response())
|
manifestLocations.map(location => this._platform.request(location, { method: "GET", format: "json", cache: true, }).response())
|
||||||
);
|
);
|
||||||
results.forEach(({ body }, i) => idToManifest.set(body.id, { manifest: body, location: manifestLocations[i] }));
|
this._themeBuilder = new ThemeBuilder(this._platform, this.preferredColorScheme);
|
||||||
this._themeBuilder = new ThemeBuilder(this._platform, idToManifest, this.preferredColorScheme);
|
|
||||||
const runtimeThemePromises: Promise<void>[] = [];
|
const runtimeThemePromises: Promise<void>[] = [];
|
||||||
for (let i = 0; i < results.length; ++i) {
|
for (let i = 0; i < results.length; ++i) {
|
||||||
const { body } = results[i];
|
const { body } = results[i];
|
||||||
try {
|
try {
|
||||||
if (body.extends) {
|
if (body.extends) {
|
||||||
const promise = this._themeBuilder.populateDerivedTheme(body, log);
|
const indexOfBaseManifest = results.findIndex(manifest => manifest.body.id === body.extends);
|
||||||
|
if (indexOfBaseManifest === -1) {
|
||||||
|
throw new Error(`Base manifest for derived theme at ${manifestLocations[i]} not found!`);
|
||||||
|
}
|
||||||
|
const {body: baseManifest} = results[indexOfBaseManifest];
|
||||||
|
const baseManifestLocation = manifestLocations[indexOfBaseManifest];
|
||||||
|
const promise = this._themeBuilder.populateDerivedTheme(body, baseManifest, baseManifestLocation, log);
|
||||||
runtimeThemePromises.push(promise);
|
runtimeThemePromises.push(promise);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -97,7 +101,7 @@ export class ThemeLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
private _populateThemeMap(manifest: ThemeManifest, manifestLocation: string, log: ILogItem) {
|
private _populateThemeMap(manifest: ThemeManifest, manifestLocation: string, log: ILogItem) {
|
||||||
log.wrap("populateThemeMap", () => {
|
log.wrap("ThemeLoader.populateThemeMap", () => {
|
||||||
/*
|
/*
|
||||||
After build has finished, the source section of each theme manifest
|
After build has finished, the source section of each theme manifest
|
||||||
contains `built-assets` which is a mapping from the theme-id to
|
contains `built-assets` which is a mapping from the theme-id to
|
||||||
|
|
Loading…
Reference in a new issue