@abi-software/simulationvuer 4.0.0 → 4.0.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/simulationvuer",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vite serve --host --force",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@abi-software/plotvuer": "1.0.7",
24
- "@opencor/opencor": "^0.20260728.1",
24
+ "@opencor/opencor": "^0.20260729.0",
25
25
  "element-plus": "2.8.4",
26
26
  "jsonschema": "^1.5.0",
27
27
  "mathjs": "^15.2.0",
package/vite.config.js CHANGED
@@ -9,17 +9,10 @@ import { defineConfig } from "vite";
9
9
 
10
10
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
11
  const pathSrc = path.resolve(__dirname, "./src");
12
-
13
- // Retrieve the version of libOpenCOR used by @opencor/opencor.
14
-
15
- const opencorPackage = JSON.parse(
16
- fs.readFileSync(
17
- path.resolve(__dirname, "node_modules/@opencor/opencor/package.json"),
18
- "utf-8",
19
- ),
12
+ const libopencorDir = path.resolve(
13
+ __dirname,
14
+ "node_modules/@opencor/opencor/dist/libopencor",
20
15
  );
21
- const libopencorVersion = opencorPackage.libopencorVersion;
22
- const libopencorUrl = `https://opencor.ws/libopencor/downloads/wasm/${libopencorVersion}`;
23
16
 
24
17
  export default defineConfig(({ command, mode }) => {
25
18
  const config = {
@@ -38,44 +31,100 @@ export default defineConfig(({ command, mode }) => {
38
31
  dts: "src/components.d.ts",
39
32
  }),
40
33
 
41
- // Rewrite the libOpenCOR import URL in @opencor/opencor to a same-origin path. This is needed because
42
- // libopencor.js constructs pthread workers via new Worker(), which requires the worker script to be
43
- // same-origin with the page. The actual files are served by the dev server proxy (see below).
34
+ // Resolve the libopencor.js import URL in @opencor/opencor's opencor.es.js so that it works for all consumers
35
+ // (not just Vite projects) and this without server configuration.
36
+ //
37
+ // In @opencor/opencor, the code uses:
38
+ // new URL("./libopencor/wasm/<version>/libopencor.js", window.location.href).href
39
+ //
40
+ // This resolves relative to the page URL, requiring the server to host libopencor.js at a page-relative path
41
+ // (which doesn't work for library consumers or static builds).
42
+ //
43
+ // We fix this by:
44
+ // - Dev (serve): rewriting to "/libopencor/libopencor.js", served by the middleware below.
45
+ // - Build (lib): rewriting to use import.meta.url, so the import resolves relative to simulationvuer.js's URL
46
+ // (same directory, libopencor.js is copied alongside it via closeBundle).
44
47
 
45
48
  {
46
- name: "opencor-local-libopencor",
47
- enforce: "pre",
48
-
49
- // Tell Vite that /libopencor/* paths are external.
50
- // Note: they are served via the dev server proxy, so Vite should not try to resolve them locally.
51
-
52
- resolveId(id) {
53
- if (id.startsWith("/libopencor/")) {
54
- return { id, external: true };
49
+ name: "opencor-libopencor",
50
+ transform(code, id) {
51
+ if (id.includes("@opencor/opencor") && id.endsWith("opencor.es.js")) {
52
+ const importRegex =
53
+ /(\/\*\s*@vite-ignore\s*\*\/[\s\n]*)(new URL\("(\.\/libopencor\/wasm\/[^/]+\/libopencor\.js)",\s*window\.location\.href\)\.href)/g;
54
+ const res = code.replace(
55
+ importRegex,
56
+ (_match, prefix, _urlExpr, urlPath) => {
57
+ if (command === "serve") {
58
+ // Dev mode: absolute path served by the middleware below.
59
+
60
+ return `${prefix}"/libopencor/libopencor.js"`;
61
+ }
62
+
63
+ // Build mode: resolve relative to the bundle's own URL.
64
+ // Note: we use replace() instead of new URL(..., import.meta.url) to avoid Vite's asset handler, which
65
+ // would inline the file as a data: URL (which breaks Emscripten's pthread Worker creation). At
66
+ // runtime, import.meta.url points to simulationvuer.js and the derived path correctly reaches
67
+ // libopencor in the same directory (copied alongside by closeBundle).
68
+
69
+ return `${prefix}import.meta.url.replace(/[^/]*$/, "") + ${JSON.stringify(urlPath.substring(2))}`;
70
+ },
71
+ );
72
+
73
+ if (res !== code) {
74
+ return {
75
+ code: res,
76
+ map: null,
77
+ };
78
+ }
55
79
  }
56
80
  },
81
+ configureServer(server) {
82
+ // Serve libopencor files from @opencor/opencor during development so the dynamic import in opencor.es.js
83
+ // resolves same-origin (required for pthread Workers).
57
84
 
58
- // Rewrite the libOpenCOR URL to same-origin path for @opencor/opencor.
59
- // Note: this is needed so the worker constructed inside libopencor.js is same-origin (i.e. no CORS error).
60
- // For production, the target server should be configured to serve /libopencor/* files.
85
+ server.middlewares.use((req, res, next) => {
86
+ const urlPath = req.url;
61
87
 
62
- transform(code, id) {
63
- if (command !== "serve") {
88
+ if (!urlPath.startsWith("/libopencor/")) {
89
+ next();
90
+
91
+ return;
92
+ }
93
+
94
+ const filePath = path.join(
95
+ libopencorDir,
96
+ urlPath.replace("/libopencor/", ""),
97
+ );
98
+
99
+ if (!fs.existsSync(filePath)) {
100
+ next();
101
+
102
+ return;
103
+ }
104
+
105
+ res.writeHead(200, {
106
+ "Content-Type": "application/javascript",
107
+ "Cross-Origin-Embedder-Policy": "require-corp",
108
+ "Cross-Origin-Resource-Policy": "same-origin",
109
+ });
110
+ res.end(fs.readFileSync(filePath));
111
+ });
112
+ },
113
+ closeBundle() {
114
+ // Copy libopencor alongside the built JavaScript file so that the dynamic import (using import.meta.url as
115
+ // base) resolves correctly. App mode puts the built JavaScript file in dist/assets while lib mode puts it in
116
+ // dist.
117
+
118
+ if (!fs.existsSync(libopencorDir)) {
64
119
  return;
65
120
  }
66
121
 
67
- if (
68
- id.includes("@opencor/opencor") &&
69
- !id.split("?")[0].endsWith(".css")
70
- ) {
71
- return {
72
- code: code.replace(
73
- /"https:\/\/opencor\.ws\/libopencor\/downloads\/wasm\/[^/]+\/libopencor\.js"/g,
74
- '"/libopencor/libopencor.js"',
75
- ),
76
- map: null,
77
- };
78
- }
122
+ const distDir = path.resolve(__dirname, "dist");
123
+ const targetDir = fs.existsSync(path.join(distDir, "assets"))
124
+ ? path.join(distDir, "assets", "libopencor")
125
+ : path.join(distDir, "libopencor");
126
+
127
+ fs.cpSync(libopencorDir, targetDir, { recursive: true, force: true });
79
128
  },
80
129
  },
81
130
  ],
@@ -115,17 +164,6 @@ export default defineConfig(({ command, mode }) => {
115
164
  config.server = {
116
165
  port: 8081,
117
166
 
118
- // Proxy /libopencor/* requests to the libOpenCOR server, so the worker constructed inside libopencor.js loads
119
- // from a same-origin path (new Worker() requires the worker script to be same-origin with the page).
120
-
121
- proxy: {
122
- "/libopencor": {
123
- target: libopencorUrl,
124
- changeOrigin: true,
125
- rewrite: (path) => path.replace(/^\/libopencor/, ""),
126
- },
127
- },
128
-
129
167
  // Emscripten pthreads require SharedArrayBuffer, which needs cross-origin isolation.
130
168
 
131
169
  headers: {
@@ -133,13 +171,6 @@ export default defineConfig(({ command, mode }) => {
133
171
  "Cross-Origin-Embedder-Policy": "require-corp",
134
172
  },
135
173
  };
136
-
137
- // Exclude @opencor/opencor from Vite's pre-bundling so our transform plugin above can rewrite the import URL in
138
- // opencor.es.js.
139
-
140
- config.optimizeDeps = {
141
- exclude: ["@opencor/opencor"],
142
- };
143
174
  config.define = {
144
175
  "process.env.HTTP_PROXY": 8081,
145
176
  global: "globalThis",