@curvenote/renderers 0.6.8 → 0.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
- import type { AnyMystDirective } from './types.js';
1
+ import type { AnyBundleDirective } from './types.js';
2
2
  export declare function AnyRenderer({ node }: {
3
- node: AnyMystDirective;
3
+ node: AnyBundleDirective;
4
4
  }): import("react/jsx-runtime").JSX.Element;
5
5
  //# sourceMappingURL=renderers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../src/any/renderers.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,2CA4G/D"}
1
+ {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../src/any/renderers.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,wBAAgB,WAAW,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,kBAAkB,CAAA;CAAE,2CAyIjE"}
@@ -22,14 +22,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
22
  import * as React from 'react';
23
23
  import { MystAnyModel } from './models.js';
24
24
  export function AnyRenderer({ node }) {
25
- var _a;
25
+ var _a, _b;
26
26
  // basic validation
27
- const validImport = node.data.import &&
28
- typeof node.data.import === 'string' &&
29
- (node.data.import.startsWith('https://') || node.data.import.startsWith('http://'));
27
+ const esmModuleUrl = (_a = node.data.esm) !== null && _a !== void 0 ? _a : node.data.import; // supports legacy import URL
28
+ const isESMModuleUrlValid = esmModuleUrl &&
29
+ typeof esmModuleUrl === 'string' &&
30
+ (esmModuleUrl.startsWith('https://') || esmModuleUrl.startsWith('http://'));
30
31
  const validJson = node.data.json && typeof node.data.json === 'object';
31
32
  const ref = React.useRef(null);
33
+ const [error, setError] = React.useState(null);
32
34
  React.useEffect(() => {
35
+ // Reset error state on node change
36
+ setError(null);
33
37
  // @see https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal#implementing_an_abortable_api
34
38
  const controller = new AbortController();
35
39
  // if already aborted just ignore
@@ -43,9 +47,10 @@ export function AnyRenderer({ node }) {
43
47
  yield (maybeCleanupInitialize === null || maybeCleanupInitialize === void 0 ? void 0 : maybeCleanupInitialize());
44
48
  }));
45
49
  // TODO: validation for import & styles URLs
46
- console.debug('AnyRenderer importing:', node.data.import);
47
- import(node.data.import).then((mod) => __awaiter(this, void 0, void 0, function* () {
48
- var _a, _b, _c, _d, _e, _f;
50
+ console.debug('AnyRenderer importing:', esmModuleUrl);
51
+ import(esmModuleUrl)
52
+ .then((mod) => __awaiter(this, void 0, void 0, function* () {
53
+ var _a, _b, _c, _d, _e, _f, _g;
49
54
  if (!ref.current)
50
55
  return;
51
56
  console.debug('AnyRenderer imported', mod);
@@ -56,7 +61,7 @@ export function AnyRenderer({ node }) {
56
61
  // clear current contents
57
62
  (_b = ref.current) === null || _b === void 0 ? void 0 : _b.replaceChildren();
58
63
  // apply container classes
59
- if (((_c = node.data.class) === null || _c === void 0 ? void 0 : _c.trim().length) > 0) {
64
+ if (node.data.class && ((_c = node.data.class) === null || _c === void 0 ? void 0 : _c.trim().length) > 0) {
60
65
  (_d = node.data.class) === null || _d === void 0 ? void 0 : _d.trim().split(' ').forEach((c) => {
61
66
  var _a;
62
67
  (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.add(c);
@@ -65,36 +70,44 @@ export function AnyRenderer({ node }) {
65
70
  // apply styles
66
71
  let rootEl = ref.current;
67
72
  const shadow = true;
68
- if (node.data.styles) {
73
+ const css = (_e = node.data.css) !== null && _e !== void 0 ? _e : node.data.styles; // supports legacy styles
74
+ if (css) {
69
75
  if (shadow) {
70
- const shadowRoot = (_e = rootEl.shadowRoot) !== null && _e !== void 0 ? _e : rootEl.attachShadow({ mode: 'open' });
76
+ const shadowRoot = (_f = rootEl.shadowRoot) !== null && _f !== void 0 ? _f : rootEl.attachShadow({ mode: 'open' });
71
77
  shadowRoot.replaceChildren();
72
78
  const shadowEl = document.createElement('div');
73
79
  shadowRoot.appendChild(shadowEl);
74
80
  const link = document.createElement('link');
75
81
  link.rel = 'stylesheet';
76
- link.href = node.data.styles;
82
+ link.href = css;
77
83
  shadowRoot.appendChild(link);
78
84
  rootEl = shadowEl;
79
85
  }
80
86
  else {
81
87
  const link = document.createElement('link');
82
88
  link.rel = 'stylesheet';
83
- link.href = node.data.styles;
89
+ link.href = css;
84
90
  rootEl.appendChild(link);
85
91
  }
86
92
  }
87
- maybeCleanupRender = yield ((_f = widget.render) === null || _f === void 0 ? void 0 : _f.call(widget, {
93
+ maybeCleanupRender = yield ((_g = widget.render) === null || _g === void 0 ? void 0 : _g.call(widget, {
88
94
  model,
89
95
  el: rootEl,
90
96
  }));
91
- }));
97
+ }))
98
+ .catch((err) => {
99
+ console.error('AnyRenderer failed to import module:', err);
100
+ setError(err instanceof Error ? err : new Error(String(err)));
101
+ });
92
102
  return () => {
93
103
  controller === null || controller === void 0 ? void 0 : controller.abort();
94
104
  };
95
105
  }, [node]);
96
- if (!validImport || !validJson) {
97
- return (_jsxs("div", { className: "p-3 space-y-2 border border-red-500 rounded-md", children: [_jsxs("div", { children: ["Invalid ", _jsx("code", { children: "any:bundle" }), " directive."] }), !validImport && (_jsxs("div", { className: "px-1", children: [_jsx("div", { children: "Invalid import URL" }), _jsx("div", { className: "text-sm text-gray-500", children: node.data.import })] })), !validJson && (_jsxs("div", { className: "px-1", children: [_jsx("div", { children: "Invalid JSON data" }), _jsx("div", { className: "text-sm text-gray-500", children: (_a = node.data.json) === null || _a === void 0 ? void 0 : _a.toString() })] }))] }));
106
+ if (error) {
107
+ return (_jsxs("details", { className: "p-3 bg-gray-100 rounded border border-gray-300 cursor-pointer", children: [_jsxs("summary", { className: "text-sm text-gray-600 select-none", children: ["Failed to load ", _jsx("code", { className: "text-xs", children: "any:bundle" }), " module."] }), _jsxs("div", { className: "pt-2 mt-2 space-y-1 text-xs border-t border-gray-200", children: [_jsxs("div", { className: "text-gray-500", children: [_jsx("span", { className: "font-medium", children: "Bundle URL:" }), " ", esmModuleUrl] }), _jsxs("div", { className: "text-gray-700", children: [_jsx("span", { className: "font-medium", children: "Error:" }), " ", error.message] })] })] }));
108
+ }
109
+ if (!isESMModuleUrlValid || !validJson) {
110
+ return (_jsxs("div", { className: "p-3 space-y-2 rounded-md border border-red-500", children: [_jsxs("div", { children: ["Invalid ", _jsx("code", { children: "any:bundle" }), " directive."] }), !isESMModuleUrlValid && (_jsxs("div", { className: "px-1", children: [_jsx("div", { children: "Invalid import URL" }), _jsx("div", { className: "text-sm text-gray-500", children: node.data.import })] })), !validJson && (_jsxs("div", { className: "px-1", children: [_jsx("div", { children: "Invalid JSON data" }), _jsx("div", { className: "text-sm text-gray-500", children: (_b = node.data.json) === null || _b === void 0 ? void 0 : _b.toString() })] }))] }));
98
111
  }
99
112
  return _jsx("div", { className: "relative w-full", ref: ref });
100
113
  }
@@ -1,4 +1,4 @@
1
- export type AnyMystDirective = {
1
+ export type AnyBundleDirective = {
2
2
  /** The type of the directive */
3
3
  type: 'block';
4
4
  /** The kind of the directive */
@@ -6,13 +6,17 @@ export type AnyMystDirective = {
6
6
  /** The data to pass to the model */
7
7
  data: {
8
8
  /** The ES module to import */
9
+ esm: string;
9
10
  import: string;
10
- /** Tailwind classes to apply to the container element */
11
- class: string;
12
- /** URL to a css stylesheet to load for the widget */
13
- styles: string;
14
11
  /** The JSON data to initialize the widget */
15
12
  json: Record<string, unknown>;
13
+ /** URL to a css stylesheet to load for the widget */
14
+ css?: string;
15
+ styles?: string;
16
+ /** Tailwind classes to apply to the container element */
17
+ class?: string;
18
+ /** A static file path, folder path or glob pattern to static files to make available to the module */
19
+ static?: string;
16
20
  };
17
21
  };
18
22
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/any/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,gCAAgC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,oCAAoC;IACpC,IAAI,EAAE;QACJ,8BAA8B;QAC9B,MAAM,EAAE,MAAM,CAAC;QACf,yDAAyD;QACzD,KAAK,EAAE,MAAM,CAAC;QACd,qDAAqD;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,6CAA6C;QAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAC/B,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/any/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gCAAgC;IAChC,IAAI,EAAE,OAAO,CAAC;IACd,gCAAgC;IAChC,IAAI,EAAE,YAAY,CAAC;IACnB,oCAAoC;IACpC,IAAI,EAAE;QACJ,8BAA8B;QAC9B,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,6CAA6C;QAC7C,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,qDAAqD;QACrD,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,yDAAyD;QACzD,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,sGAAsG;QACtG,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@curvenote/renderers",
3
- "version": "0.6.8",
3
+ "version": "0.6.9",
4
4
  "type": "module",
5
5
  "exports": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -21,11 +21,11 @@
21
21
  "build": "npm-run-all -l clean -p build:esm"
22
22
  },
23
23
  "dependencies": {
24
- "@curvenote/ext-blog": "^0.6.8",
25
- "@curvenote/ext-footer": "^0.6.8",
26
- "@curvenote/ext-landing": "^0.6.8",
27
- "@curvenote/ext-person": "^0.6.8",
28
- "@curvenote/theme": "^0.6.8",
24
+ "@curvenote/ext-blog": "^0.6.9",
25
+ "@curvenote/ext-footer": "^0.6.9",
26
+ "@curvenote/ext-landing": "^0.6.9",
27
+ "@curvenote/ext-person": "^0.6.9",
28
+ "@curvenote/theme": "^0.6.9",
29
29
  "@heroicons/react": "^2.1.5",
30
30
  "@myst-theme/providers": "^0.14.1",
31
31
  "@scienceicons/myst": "^1.0.4",