Skip to content

Commit c4eb412

Browse files
Merge pull request #139 from opencomponents/esm-template
add ESM template support
2 parents 0f62c5a + 96ebb88 commit c4eb412

File tree

4 files changed

+50
-6
lines changed

4 files changed

+50
-6
lines changed

.github/workflows/node.js.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616

1717
strategy:
1818
matrix:
19-
node-version: [18.x, 20.x, 22.x]
19+
node-version: [20.x, 20.x, 22.x]
2020
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
2121

2222
steps:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "oc-client-browser",
3-
"version": "2.0.0",
3+
"version": "2.0.1",
44
"description": "OC browser client",
55
"main": "index.js",
66
"types": "index.d.ts",

src/oc-client.js

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* globals __CLIENT_VERSION__, __REGISTERED_TEMPLATES_PLACEHOLDER__, __DEFAULT_RETRY_INTERVAL__, __DEFAULT_RETRY_LIMIT__, __DEFAULT_DISABLE_LOADER__, __DISABLE_LEGACY_TEMPLATES__, __EXTERNALS__ */
1+
/* globals __CLIENT_VERSION__, __REGISTERED_TEMPLATES_PLACEHOLDER__, __DEFAULT_RETRY_INTERVAL__, __DEFAULT_RETRY_LIMIT__, __DEFAULT_DISABLE_LOADER__, __DISABLE_LEGACY_TEMPLATES__, __EXTERNALS__, __IMPORTS__ */
22
import { decode } from "@rdevis/turbo-stream";
33

44
export function createOc(oc) {
@@ -71,6 +71,7 @@ export function createOc(oc) {
7171

7272
let registeredTemplates = __REGISTERED_TEMPLATES_PLACEHOLDER__;
7373
let externals = __EXTERNALS__;
74+
let imports = __IMPORTS__;
7475

7576
let registerTemplates = (templates, overwrite) => {
7677
templates = Array.isArray(templates) ? templates : [templates];
@@ -211,7 +212,9 @@ export function createOc(oc) {
211212
setAttribute(dataRenderingAttribute, false);
212213
setAttribute("data-version", dataVersion);
213214
setAttribute("data-id", data.ocId);
214-
component.innerHTML = data.html;
215+
if (typeof data.html === "string") {
216+
component.innerHTML = data.html;
217+
}
215218
// If the html contains <scripts> tags, innerHTML will not execute them.
216219
// So we need to do it manually.
217220
reanimateScripts(component);
@@ -242,7 +245,9 @@ export function createOc(oc) {
242245
isRequired("baseUrl", baseUrl);
243246
isRequired("name", name);
244247
if (options.action) {
245-
baseUrl = `${baseUrl}~actions/${options.action}/${options.name}/${options.version || ""}`;
248+
baseUrl = `${baseUrl}~actions/${options.action}/${options.name}/${
249+
options.version || ""
250+
}`;
246251
}
247252
let parameters = { ...ocConf.globalParameters, ...options.parameters };
248253
let data = options.action
@@ -392,6 +397,14 @@ export function createOc(oc) {
392397
},
393398
};
394399
})();
400+
if (Object.keys(imports).length > 0) {
401+
$document.head.appendChild(
402+
Object.assign($document.createElement("script"), {
403+
type: "importmap",
404+
textContent: JSON.stringify({ imports }),
405+
}),
406+
);
407+
}
395408

396409
callback();
397410

@@ -411,6 +424,34 @@ export function createOc(oc) {
411424
}
412425
};
413426

427+
const renderOc = (template, apiResponse, callback) => {
428+
const isEsm = !!apiResponse.data?.component?.esm;
429+
430+
if (isEsm) {
431+
renderEsm(apiResponse.data, callback);
432+
} else {
433+
oc.render(template, apiResponse.data, callback);
434+
}
435+
};
436+
437+
const renderEsm = async (data, callback) => {
438+
try {
439+
const { _staticPath, _componentName, _componentVersion } =
440+
data.component.props;
441+
window.oc._esm = window.oc._esm || {};
442+
window.oc._esm[`${_componentName}@${_componentVersion}`] = (args) => {
443+
return _staticPath + "public/" + args;
444+
};
445+
446+
const { mount } = await import(data.component.src);
447+
mount(data.element, data.component.props);
448+
callback(null);
449+
} catch (error) {
450+
console.error("Error rendering ESM component", error);
451+
callback(error);
452+
}
453+
};
454+
414455
oc.render = (compiledViewInfo, model, callback) => {
415456
oc.ready(() => {
416457
// TODO: integrate with oc-empty-response-handler module
@@ -541,7 +582,8 @@ export function createOc(oc) {
541582
let template = apiResponse.template;
542583
apiResponse.data.id = ocId;
543584
apiResponse.data.element = element;
544-
oc.render(template, apiResponse.data, (err, html) => {
585+
586+
renderOc(template, apiResponse, (err, html) => {
545587
if (err) {
546588
callback(
547589
interpolate(MESSAGES_ERRORS_RENDERING, apiResponse.href) +

tasks/compile.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ function parseConf(conf) {
5656

5757
return {
5858
externals: conf.externals || [],
59+
imports: conf.imports || {},
5960
retryLimit: conf.retryLimit || 30,
6061
retryInterval: conf.retryInterval || 5000,
6162
disableLegacyTemplates: disableLegacyTemplates,
@@ -82,6 +83,7 @@ function getBuildOptions(conf = {}) {
8283
parsedConf.templates,
8384
),
8485
__EXTERNALS__: JSON.stringify(parsedConf.externals),
86+
__IMPORTS__: JSON.stringify(parsedConf.imports),
8587
__DEFAULT_RETRY_LIMIT__: JSON.stringify(parsedConf.retryLimit),
8688
__DEFAULT_RETRY_INTERVAL__: JSON.stringify(parsedConf.retryInterval),
8789
__DEFAULT_DISABLE_LOADER__: JSON.stringify(parsedConf.disableLoader),

0 commit comments

Comments
 (0)