react-visualizer 4.0.0 → 5.0.0

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.
package/README.md CHANGED
@@ -1,8 +1,32 @@
1
1
  # react-visualizer
2
2
 
3
- The Visualizer in a react component
3
+ Visualizer in a react component. Visualizer index page generator.
4
4
 
5
- ## Properties
5
+ ## makeVisualizerPage
6
+
7
+ Generate an HTML page which serves the Visualizer, as a Node.js API or as a CLI command.
8
+
9
+ CLI example:
10
+
11
+ ```bash
12
+ npx react-visualizer makeVisualizerPage --help
13
+ ```
14
+
15
+ Node.js API: see options of `makeVisualizerPage` function.
16
+
17
+ ## Visualizer
18
+
19
+ Component which instantiates a visualizer iframe. Pass it a URL generated by `makeVisualizerPage`.
20
+
21
+ See component props for more information.
22
+
23
+ ## OldVisualizer
24
+
25
+ The legacy visualizer component works by creating the visualizer page dynamically with a blob URL.
26
+
27
+ It is not recommended to use it anymore.
28
+
29
+ ### Properties
6
30
 
7
31
  - `cdn` - URL of the CDN that will serve the Visualizer. Default: https://www.lactame.com/visualizer
8
32
  - `fallbackVersion` - Visualizer fallback version used if no valid version is found. Default: 'latest'.
@@ -3,8 +3,16 @@
3
3
  const { parseArgs } = require('node:util');
4
4
  const makeVisualizerPage = require('../src/makeVisualizerPage');
5
5
  const { writeFileSync } = require('node:fs');
6
+ const assert = require('node:assert');
7
+
8
+ let argv = process.argv.slice(2);
9
+ const startIndex = argv.findIndex((arg) => arg === 'makeVisualizerPage');
10
+ if (startIndex > -1) {
11
+ argv = argv.slice(startIndex + 1);
12
+ }
6
13
 
7
14
  const { values: args } = parseArgs({
15
+ args: argv,
8
16
  options: {
9
17
  help: {
10
18
  type: 'boolean',
@@ -13,6 +21,9 @@ const { values: args } = parseArgs({
13
21
  fallbackVersion: {
14
22
  type: 'string',
15
23
  },
24
+ loadversion: {
25
+ type: 'string',
26
+ },
16
27
  cdn: {
17
28
  type: 'string',
18
29
  },
@@ -44,6 +55,13 @@ Options:
44
55
  --fallbackVersion <string>
45
56
  Visualizer version to use if it is not specified in the search url and not loaded from the view
46
57
 
58
+ --loadversion <'none' | 'exact' | 'major-latest'>
59
+ What version to load based on the version referenced by the view.
60
+ 'exact': load exactly the version of the view.
61
+ 'latest-major': use the major version of the view, but its latest version.
62
+ 'none': do not use the view to decide which version to load.
63
+ Default: 'none'
64
+
47
65
  --cdn <string>
48
66
  CDN base URL for visualizer assets
49
67
 
@@ -51,8 +69,10 @@ Options:
51
69
  Output file path to which to write the html file
52
70
  Default: visualizer.html
53
71
 
54
- --queryType <string>
55
- Where the search parameters should be read from: 'fragment' or 'query'
72
+ --queryType <'fragment' | 'query'>
73
+ Where the search parameters should be read from.
74
+ 'query': Uses the regular query string of the URL
75
+ 'fragment': Uses the fragment identifier (aka hash) of the URL as query string
56
76
  Default: query
57
77
  `);
58
78
  }
@@ -9,10 +9,20 @@ function relativeUrl(from, to) {
9
9
  class OldVisualizer extends React.PureComponent {
10
10
  render() {
11
11
  const currentHref = window.location.href;
12
- let cdn = this.props.cdn ? this.props.cdn.replace(/\/$/, "") : "https://www.lactame.com/visualizer";
13
- cdn = relativeUrl(currentHref, cdn);
14
- let scripts = this.props.scripts || [];
15
- scripts = scripts.map((script) => {
12
+ const {
13
+ cdn,
14
+ viewURL,
15
+ dataURL,
16
+ config,
17
+ style,
18
+ scripts = [],
19
+ loadversion,
20
+ fallbackVersion,
21
+ queryParameters
22
+ } = this.props;
23
+ let finalCDN = cdn ? cdn.replace(/\/$/, "") : "https://www.lactame.com/visualizer";
24
+ finalCDN = relativeUrl(currentHref, finalCDN);
25
+ const finalScripts = scripts.map((script) => {
16
26
  if (script.url || typeof script === "string") {
17
27
  return {
18
28
  url: relativeUrl(currentHref, script.url || script)
@@ -22,9 +32,10 @@ class OldVisualizer extends React.PureComponent {
22
32
  }
23
33
  });
24
34
  const page = makeVisualizerPage({
25
- cdn,
26
- fallbackVersion: this.props.fallbackVersion,
27
- scripts
35
+ cdn: finalCDN,
36
+ scripts: finalScripts,
37
+ loadversion,
38
+ fallbackVersion
28
39
  });
29
40
  if (!urls.has(page)) {
30
41
  urls.set(
@@ -37,11 +48,11 @@ class OldVisualizer extends React.PureComponent {
37
48
  ReactVisualizer,
38
49
  {
39
50
  url,
40
- viewURL: this.props.viewURL,
41
- dataURL: this.props.dataURL,
42
- config: this.props.config,
43
- version: this.props.version,
44
- style: this.props.style
51
+ viewURL,
52
+ dataURL,
53
+ config,
54
+ queryParameters,
55
+ style
45
56
  }
46
57
  );
47
58
  }
@@ -7,11 +7,14 @@ function relativeUrl(from, to) {
7
7
  function Visualizer(props) {
8
8
  const currentHref = window.location.href;
9
9
  let viewURL = props.viewURL || "";
10
- if (viewURL) viewURL = relativeUrl(currentHref, viewURL);
11
10
  let dataURL = props.dataURL || "";
12
- if (dataURL) dataURL = relativeUrl(currentHref, dataURL);
13
11
  let config = props.config || "";
14
- const version = props.version || "latest";
12
+ if (viewURL) {
13
+ viewURL = relativeUrl(currentHref, viewURL);
14
+ }
15
+ if (dataURL) {
16
+ dataURL = relativeUrl(currentHref, dataURL);
17
+ }
15
18
  if (typeof config === "object" && config !== null) {
16
19
  if (config.header && config.header.elements) {
17
20
  config = JSON.parse(JSON.stringify(config));
@@ -36,19 +39,25 @@ function Visualizer(props) {
36
39
  position: "absolute",
37
40
  border: "none"
38
41
  };
39
- let query = ["viewURL", viewURL, "dataURL", dataURL, "config", config];
40
- query = query.map(function(v, i) {
41
- if (i % 2 === 1) return query[i - 1] + "=" + encodeURIComponent(query[i]);
42
- }).filter(function(v) {
43
- return v !== void 0;
44
- });
45
- query = query.join("&");
46
- if (version !== "auto" || !viewURL) {
47
- const v = version === "auto" ? "latest" : version;
48
- query += "&v=" + v;
49
- } else {
50
- query += "&loadversion=true";
42
+ const search = new URLSearchParams();
43
+ const query = {
44
+ viewURL,
45
+ dataURL,
46
+ config,
47
+ ...props.queryParameters
48
+ };
49
+ for (let [key, value] of Object.entries(query)) {
50
+ if (value) {
51
+ search.set(key, value);
52
+ }
51
53
  }
52
- return /* @__PURE__ */ React.createElement("iframe", { allowFullScreen: true, src: props.url + "#?" + query, style });
54
+ return /* @__PURE__ */ React.createElement(
55
+ "iframe",
56
+ {
57
+ allowFullScreen: true,
58
+ src: props.url + "#?" + search.toString(),
59
+ style
60
+ }
61
+ );
53
62
  }
54
63
  module.exports = React.memo(Visualizer);
@@ -5,8 +5,11 @@ function makeVisualizerPage(options = {}) {
5
5
  cdn = "https://www.lactame.com/visualizer",
6
6
  fallbackVersion = "latest",
7
7
  queryType = "fragment",
8
+ loadversion = "none",
8
9
  scripts = []
9
10
  } = options;
11
+ validateQueryType(queryType);
12
+ validateLoadVersion(loadversion);
10
13
  const scriptsStr = scripts.reduce(function(value, script) {
11
14
  if (script.url) {
12
15
  return value + `<script src="${script.url}"><\/script>
@@ -18,6 +21,22 @@ function makeVisualizerPage(options = {}) {
18
21
  throw new Error("script must have url or content");
19
22
  }
20
23
  }, "");
21
- return template.replaceAll("{{ cdn }}", cdn).replaceAll("{{ fallbackVersion }}", fallbackVersion).replace("{{ scripts }}", scriptsStr).replace("{{ queryType }}", queryType);
24
+ return template.replace("{{ cdn }}", cdn).replace("{{ fallbackVersion }}", fallbackVersion).replace("{{ scripts }}", scriptsStr).replace("{{ queryType }}", queryType).replace("{{ loadversion }}", loadversion);
22
25
  }
23
26
  module.exports = makeVisualizerPage;
27
+ const validLoadversion = ["none", "exact", "latest-major"];
28
+ function validateLoadVersion(loadversion) {
29
+ if (!validLoadversion.includes(loadversion)) {
30
+ throw new Error(
31
+ `Invalid "loadversion" parameter: ${loadversion}. Allowed values: ${validLoadversion.join(", ")}`
32
+ );
33
+ }
34
+ }
35
+ const validQueryType = ["fragment", "query"];
36
+ function validateQueryType(queryType) {
37
+ if (!validQueryType.includes(queryType)) {
38
+ throw new Error(
39
+ `Invalid "queryType" parameter: ${queryType}, allowed values: ${validQueryType.join(", ")}`
40
+ );
41
+ }
42
+ }
@@ -36,17 +36,18 @@ window.onload = function () {
36
36
  const search = new URLSearchParams(query.startsWith("#") ? query.slice(1) : query);
37
37
  const url = search.get('viewURL');
38
38
  const v = search.get('v');
39
- const loadversion = search.get('loadversion');
39
+ const loadversion = search.get('loadversion') || '{{ loadversion }}';
40
+ const fallbackVersion = search.get('fallbackVersion') || '{{ fallbackVersion }}';
40
41
  if (v) {
41
42
  addVisualizer(checkVersion(v));
42
43
  return;
43
44
  }
44
45
 
45
- if (!loadversion || !url) {
46
- addVisualizer('{{ fallbackVersion }}');
46
+ if (loadversion === 'none' || !url) {
47
+ addVisualizer(fallbackVersion);
47
48
  } else {
48
49
  const viewReg = new RegExp('/view.json$');
49
- var docUrl = url.replace(viewReg, '');
50
+ const docUrl = url.replace(viewReg, '');
50
51
  fetchUrl(docUrl)
51
52
  .then(function (data) {
52
53
  if (!data.version && (!data.$content || !data.$content.version))
@@ -70,11 +71,10 @@ window.onload = function () {
70
71
  }
71
72
 
72
73
  function addVisualizer(version) {
73
- var cdn = '{{ cdn }}';
74
- var visualizer = document.createElement('script');
75
- var prefix = cdn;
76
- var datamain = prefix + '/' + version + '/init';
77
- var requirejs = prefix + '/' + version + '/components/requirejs/require.js';
74
+ const cdn = '{{ cdn }}';
75
+ const visualizer = document.createElement('script');
76
+ const datamain = cdn + '/' + version + '/init';
77
+ const requirejs = cdn + '/' + version + '/components/requirejs/require.js';
78
78
 
79
79
  visualizer.setAttribute('data-main', datamain);
80
80
  visualizer.setAttribute('src', requirejs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-visualizer",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "The visualizer in a react component",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -32,6 +32,7 @@
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^24.10.13",
35
+ "@types/react": "^18.3.28",
35
36
  "esbuild": "^0.27.3",
36
37
  "prettier": "^3.8.1",
37
38
  "react": "^18.3.1",