diff --git a/apps/web/src/components/Inspector.tsx b/apps/web/src/components/Inspector.tsx
index 9534bf58..f8b1ba20 100644
--- a/apps/web/src/components/Inspector.tsx
+++ b/apps/web/src/components/Inspector.tsx
@@ -232,6 +232,21 @@ export function Inspector() {
}}
/>
+
+
+ {
+ updateFlags({
+ enableBlockHeightVersioning: e.target.checked,
+ });
+ }}
+ />
+
diff --git a/packages/application/src/hooks/useCompiler.ts b/packages/application/src/hooks/useCompiler.ts
index 1502a6a8..0869bd14 100644
--- a/packages/application/src/hooks/useCompiler.ts
+++ b/packages/application/src/hooks/useCompiler.ts
@@ -34,12 +34,14 @@ export function useCompiler({
action: 'init',
localComponents,
preactVersion: config.preactVersion,
+ enableBlockHeightVersioning: config.flags?.enableBlockHeightVersioning,
});
}, [
compiler,
config.flags?.bosLoaderUrl,
config.preactVersion,
localComponents,
+ config.flags?.enableBlockHeightVersioning,
]);
return compiler;
diff --git a/packages/application/src/hooks/useWebEngineSandbox.ts b/packages/application/src/hooks/useWebEngineSandbox.ts
index 73269e8f..b97c3ad6 100644
--- a/packages/application/src/hooks/useWebEngineSandbox.ts
+++ b/packages/application/src/hooks/useWebEngineSandbox.ts
@@ -13,6 +13,7 @@ export function useWebEngineSandbox({
}: UseWebEngineSandboxParams) {
const [nonce, setNonce] = useState('');
const preactVersion = config.preactVersion;
+ const enableBlockHeightVersioning = config.flags?.enableBlockHeightVersioning;
const { appendStylesheet, resetContainerStylesheet } = useCss();
const compiler = useCompiler({ config, localComponents });
@@ -50,6 +51,7 @@ export function useWebEngineSandbox({
action: 'init',
localComponents,
preactVersion,
+ enableBlockHeightVersioning,
});
compiler?.postMessage({
@@ -63,6 +65,7 @@ export function useWebEngineSandbox({
preactVersion,
rootComponentPath,
setComponents,
+ enableBlockHeightVersioning,
]);
return {
diff --git a/packages/application/src/types.ts b/packages/application/src/types.ts
index 5f00bbde..b49e4459 100644
--- a/packages/application/src/types.ts
+++ b/packages/application/src/types.ts
@@ -147,4 +147,5 @@ export interface WebEngineConfiguration {
export interface WebEngineFlags {
bosLoaderUrl?: string;
showContainerBoundaries?: boolean;
+ enableBlockHeightVersioning?: boolean;
}
diff --git a/packages/compiler/src/compiler.ts b/packages/compiler/src/compiler.ts
index e8056319..d2561e9f 100644
--- a/packages/compiler/src/compiler.ts
+++ b/packages/compiler/src/compiler.ts
@@ -31,6 +31,7 @@ export class ComponentCompiler {
private compiledSourceCache: Map;
private readonly sendWorkerMessage: SendMessageCallback;
private preactVersion?: string;
+ private enableBlockHeightVersioning?: boolean;
private social: SocialDb;
private readonly cssParser: CssParser;
@@ -45,8 +46,13 @@ export class ComponentCompiler {
});
}
- init({ localComponents, preactVersion }: CompilerInitAction) {
+ init({
+ localComponents,
+ preactVersion,
+ enableBlockHeightVersioning,
+ }: CompilerInitAction) {
this.preactVersion = preactVersion;
+ this.enableBlockHeightVersioning = enableBlockHeightVersioning;
this.bosSourceCache.clear();
this.compiledSourceCache.clear();
@@ -68,7 +74,11 @@ export class ComponentCompiler {
(componentPath) => !this.bosSourceCache.has(componentPath)
);
if (unfetchedPaths.length > 0) {
- const pathsFetch = fetchComponentSources(this.social, unfetchedPaths);
+ const pathsFetch = fetchComponentSources(
+ this.social,
+ unfetchedPaths,
+ this.enableBlockHeightVersioning
+ );
unfetchedPaths.forEach((componentPath) => {
this.bosSourceCache.set(
componentPath,
@@ -246,7 +256,15 @@ export class ComponentCompiler {
// wait on CSS initialization
await this.cssParser.init();
- const componentPath = componentId.split('##')[0];
+ let [componentPath] = componentId.split('##');
+ const [componentPathWithoutBlockHeight, blockHeight] =
+ componentPath.split('@');
+ if (blockHeight && !this.enableBlockHeightVersioning) {
+ console.warn(
+ `${componentPath} has a block height specified, but the "enableBlockHeightVersioning" flag is disabled. The latest version of Component will be used.`
+ );
+ componentPath = componentPathWithoutBlockHeight;
+ }
const moduleEntry = await this.getComponentSources([componentPath]).get(
componentPath
);
diff --git a/packages/compiler/src/source.ts b/packages/compiler/src/source.ts
index 0cb75a41..f4aa66a4 100644
--- a/packages/compiler/src/source.ts
+++ b/packages/compiler/src/source.ts
@@ -8,7 +8,8 @@ import { ComponentEntry } from './types';
export async function fetchComponentSources(
social: SocialDb,
- componentPaths: string[]
+ componentPaths: string[],
+ enableBlockHeightVersioning?: boolean
) {
/*
Typically, you'd want to pass a generic to `social.get()`. This generic
@@ -25,15 +26,96 @@ export async function fetchComponentSources(
};
};
- const keys = componentPaths.map(
- (p) => p.split('/').join(`/${SOCIAL_COMPONENT_NAMESPACE}/`) + '/*'
- );
+ let aggregatedResponses;
+
+ if (enableBlockHeightVersioning) {
+ /**
+ * Requested components mapped by the block heights to reduce the amount of social requests
+ * If no block height specified - the "" key is used
+ */
+ const componentsByBlockHeight = componentPaths.reduce(
+ (pathsByBlockHeight, componentPath) => {
+ const [path, blockHeight] = componentPath.split('@');
+ const blockHeightKey = blockHeight || '';
+
+ if (!pathsByBlockHeight[blockHeightKey]) {
+ pathsByBlockHeight[blockHeightKey] = [];
+ }
+
+ pathsByBlockHeight[blockHeightKey].push(
+ path.split('/').join(`/${SOCIAL_COMPONENT_NAMESPACE}/`) + '/*'
+ );
+
+ return pathsByBlockHeight;
+ },
+ {} as Record
+ );
+
+ const componentsByBlockHeightArr = Object.entries(componentsByBlockHeight);
+
+ const responsesWithBlockHeight = await Promise.all(
+ componentsByBlockHeightArr.map(async ([blockId, keys]) => {
+ const response = (await social.get({
+ keys,
+ blockId: Number(blockId),
+ })) as SocialComponentsByAuthor;
+
+ if (!blockId) {
+ return response;
+ }
+
+ return Object.fromEntries(
+ Object.entries(response).map(
+ ([author, { [SOCIAL_COMPONENT_NAMESPACE]: componentEntry }]) => [
+ author,
+ {
+ [SOCIAL_COMPONENT_NAMESPACE]: Object.fromEntries(
+ Object.entries(componentEntry).map(
+ ([componentPath, componentSource]) => [
+ `${componentPath}@${blockId}`,
+ componentSource,
+ ]
+ )
+ ),
+ },
+ ]
+ )
+ );
+ })
+ );
+
+ aggregatedResponses = responsesWithBlockHeight.reduce(
+ (accumulator, response) => {
+ Object.entries(response).forEach(
+ ([author, { [SOCIAL_COMPONENT_NAMESPACE]: componentEntry }]) => {
+ if (accumulator[author]?.[SOCIAL_COMPONENT_NAMESPACE]) {
+ accumulator[author][SOCIAL_COMPONENT_NAMESPACE] = {
+ ...accumulator[author][SOCIAL_COMPONENT_NAMESPACE],
+ ...componentEntry,
+ };
+ } else {
+ accumulator[author] = {
+ [SOCIAL_COMPONENT_NAMESPACE]: componentEntry,
+ };
+ }
+ }
+ );
+
+ return accumulator;
+ },
+ {} as SocialComponentsByAuthor
+ );
+ } else {
+ const keys = componentPaths.map(
+ (p) => p.split('/').join(`/${SOCIAL_COMPONENT_NAMESPACE}/`) + '/*'
+ );
- const response = (await social.get({
- keys,
- })) as SocialComponentsByAuthor;
+ aggregatedResponses = (await social.get({
+ keys,
+ })) as SocialComponentsByAuthor;
+ }
- return Object.entries(response).reduce(
+ return Object.entries(aggregatedResponses).reduce(
(sources, [author, { [SOCIAL_COMPONENT_NAMESPACE]: componentEntry }]) => {
Object.entries(componentEntry).forEach(([componentName, component]) => {
if (component) {
diff --git a/packages/compiler/src/transpile.ts b/packages/compiler/src/transpile.ts
index 508b9b61..de326366 100644
--- a/packages/compiler/src/transpile.ts
+++ b/packages/compiler/src/transpile.ts
@@ -23,7 +23,7 @@ import type { ImportExpression, ModuleExport, ModuleImport } from './types';
/**
* Derive a BOS Component path from a relative import
- * @param componentPath poth of the Component importing another BOS Component via relative path
+ * @param componentPath path of the Component importing another BOS Component via relative path
* @param componentImport import metadata for the relative import
*/
export function deriveComponentPath(
diff --git a/packages/compiler/src/types.ts b/packages/compiler/src/types.ts
index 64749305..43498e24 100644
--- a/packages/compiler/src/types.ts
+++ b/packages/compiler/src/types.ts
@@ -15,6 +15,7 @@ export interface CompilerInitAction {
action: 'init';
localComponents?: LocalComponentMap;
preactVersion: string;
+ enableBlockHeightVersioning?: boolean;
}
export interface ComponentCompilerResponse {