Skip to content

Commit 898a1f8

Browse files
committed
Merge branch 'master' of https://github.com/elalish/manifold.git into development
2 parents 8259f02 + 0b527ea commit 898a1f8

36 files changed

Lines changed: 1683 additions & 1128 deletions

.github/workflows/check_format.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ jobs:
1515
- uses: DoozyX/clang-format-lint-action@v0.20
1616
with:
1717
source: '.'
18-
exclude: '*/third_party'
1918
extensions: 'h,cpp,js,ts,html'
2019
clangFormatVersion: 20
2120
- uses: actions/setup-python@v5

.github/workflows/publish_npm.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@ jobs:
1313
- uses: actions/checkout@v4
1414

1515
- name: Setup Node
16-
uses: actions/setup-node@v4
16+
uses: actions/setup-node@v6
1717
with:
18-
node-version: 20
18+
node-version: 25
1919
registry-url: 'https://registry.npmjs.org'
2020

21+
- name: Update npm # Ensure npm 11.5.1 or later for trusted publishing
22+
run: npm install -g npm@latest
23+
2124
- name: Download built examples
2225
uses: dawidd6/action-download-artifact@v6
2326
with:

bindings/wasm/examples/editor/editor-examples.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import godelEscherBach from '../../test/examples/godel-escher-bach.ts?raw';
44
import gyroidModule from '../../test/examples/gyroid-module.ts?raw';
55
import heart from '../../test/examples/heart.mjs?raw';
66
import importManifold from '../../test/examples/import-manifold.ts?raw';
7+
import importModel from '../../test/examples/import-model.ts?raw';
78
import intro from '../../test/examples/intro.mjs?raw';
89
import involuteGearLibrary from '../../test/examples/involute-gear-library.ts?raw';
910
import mengerSponge from '../../test/examples/menger-sponge.mjs?raw';
@@ -28,6 +29,7 @@ examples.set('Gyroid Module', gyroidModule);
2829
examples.set('Gear Bearing', gearBearing);
2930
examples.set('involute-gear-library', involuteGearLibrary);
3031
examples.set('Voronoi', voronoi);
32+
examples.set('Import Model', importModel);
3133
examples.set('Import Manifold', importManifold);
3234
examples.set('Gödel, Escher, Bach', godelEscherBach)
3335

bindings/wasm/examples/editor/editor.js

Lines changed: 50 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
import esbuildWasmUrl from 'esbuild-wasm/esbuild.wasm?url';
1818
import ManifoldWorker from 'manifold-3d/lib/worker.bundled.js?worker';
1919
import manifoldWasmUrl from 'manifold-3d/manifold.wasm?url';
20-
import {AutoTypings, LocalStorageCache} from 'monaco-editor-auto-typings';
20+
import {AutoTypings, JsDelivrSourceResolver, LocalStorageCache} from 'monaco-editor-auto-typings';
2121
import * as monaco from 'monaco-editor/esm/vs/editor/editor.main';
2222
// '?worker' is vite convention to load a module as a web worker.
2323
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
@@ -28,8 +28,13 @@ const CODE_START = '<code>';
2828
const exampleFunctions = self.examples;
2929

3030
if (navigator.serviceWorker) {
31-
navigator.serviceWorker.register(
32-
'/service-worker.js', {scope: './index.html'});
31+
// Resolve against the current page URL so production asset paths don't
32+
// redirect registration into /assets.
33+
const serviceWorkerUrl = new URL('./service-worker.js', window.location.href);
34+
navigator.serviceWorker.register(serviceWorkerUrl, {scope: './'})
35+
.catch(error => {
36+
console.error('Service worker registration failed:', error);
37+
});
3338
}
3439

3540
let editor = undefined;
@@ -307,6 +312,7 @@ async function createEditor() {
307312
editor = monaco.editor.create(document.getElementById('editor'), {
308313
language: 'typescript',
309314
automaticLayout: true,
315+
minimap: {enabled: false},
310316
});
311317

312318
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
@@ -316,15 +322,20 @@ async function createEditor() {
316322
});
317323

318324
// Make sure `manifold-3d/manifoldCAD` types are available for import.
325+
const manifoldCADTypesUrl =
326+
new URL('./manifoldCAD.d.ts', window.location.href);
327+
const manifoldCADGlobalsTypesUrl =
328+
new URL('./manifoldCADGlobals.d.ts', window.location.href);
329+
319330
monaco.languages.typescript.typescriptDefaults.addExtraLib(
320-
await (await fetch('/manifoldCAD.d.ts')).text(),
331+
await (await fetch(manifoldCADTypesUrl)).text(),
321332
'inmemory://model/node_modules/manifold-3d/manifoldCAD.d.ts');
322333

323334
// Types in the global namespace for top-level scripts.
324335
// This could be improved in the future. API-Extractor intentionally doesn't
325336
// global variables, so another tool may be a better fit.
326337
monaco.languages.typescript.typescriptDefaults.addExtraLib(
327-
(await (await fetch('/manifoldCADGlobals.d.ts')).text())
338+
(await (await fetch(manifoldCADGlobalsTypesUrl)).text())
328339
.replace(/^export /gm, ''));
329340

330341
// Load up all scripts so that monaco can check types of multi-file models.
@@ -333,16 +344,39 @@ async function createEditor() {
333344
}
334345

335346
// Initialize auto typing on monaco editor.
347+
const typeIndicator = document.getElementById('type-indicator');
336348
self.window.typecache = new LocalStorageCache();
349+
350+
// We inject manifold-3d typings locally above, so avoid extra CDN probes for
351+
// that package path. This prevents noisy 404s in production logs.
352+
const jsDelivrResolver = new JsDelivrSourceResolver();
353+
const sourceResolver = {
354+
resolvePackageJson: async (packageName, version, subPath) => {
355+
if (packageName === 'manifold-3d') return '';
356+
return jsDelivrResolver.resolvePackageJson(packageName, version, subPath);
357+
},
358+
resolveSourceFile: async (packageName, version, path) => {
359+
if (packageName === 'manifold-3d') return '';
360+
return jsDelivrResolver.resolveSourceFile(packageName, version, path);
361+
}
362+
};
363+
337364
const autoTypings = await AutoTypings.create(editor, {
365+
sourceResolver,
338366
sourceCache: self.window.typecache,
339-
onError: e => {console.error(e)},
340-
onUpdate: (update, text) => {console.debug(text)},
367+
onError: e => {
368+
console.error(e);
369+
if (typeIndicator) typeIndicator.textContent = '';
370+
},
371+
onUpdate: (_, text) => {
372+
if (typeIndicator) typeIndicator.textContent = 'Fetching types...';
373+
console.debug(text);
374+
},
341375
onUpdateVersions: (versions) => {
342-
console.debug(versions)
376+
if (typeIndicator) typeIndicator.textContent = '';
377+
console.debug(versions);
343378
}
344379
});
345-
346380
for (const [name] of exampleFunctions) {
347381
const button = createDropdownItem(name);
348382
fileDropdown.appendChild(button.parentElement);
@@ -609,7 +643,7 @@ runButton.onclick = function() {
609643
}
610644
};
611645

612-
function clickSave(saveButton, filename, outputName) {
646+
function clickSave(saveButton, extension, outputName) {
613647
const container = saveButton.parentElement;
614648
return () => {
615649
const oldSave = saveContainer.firstElementChild;
@@ -619,14 +653,17 @@ function clickSave(saveButton, filename, outputName) {
619653
container.appendChild(saveArrow.parentElement);
620654
}
621655
const link = document.createElement('a');
622-
link.download = filename;
656+
657+
link.download =
658+
`${currentFileElement.textContent.trim() || 'manifold'}.${extension}`;
659+
623660
link.href = output[outputName];
624661
link.click();
625662
};
626663
}
627664

628665
const glbButton = document.querySelector('#glb');
629-
glbButton.onclick = clickSave(glbButton, 'manifold.glb', 'glbURL');
666+
glbButton.onclick = clickSave(glbButton, 'glb', 'glbURL');
630667

631668
const threemfButton = document.querySelector('#threemf');
632-
threemfButton.onclick = clickSave(threemfButton, 'manifold.3mf', 'threeMFURL');
669+
threemfButton.onclick = clickSave(threemfButton, '3mf', 'threeMFURL');

bindings/wasm/examples/editor/index.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<meta property="og:image:width" content="850">
1616
<meta property="og:image:height" content="850">
1717
<link rel="shortcut icon" type="image/png" href="https://elalish.github.io/manifold/samples/models/favicon.png">
18-
<link rel="manifest" href="/manifest.json">
18+
<link rel="manifest" href="./manifest.json">
1919
<link type="text/css" href="editor.css" rel="stylesheet">
2020
<script type="application/ld+json">
2121
{
@@ -39,13 +39,14 @@
3939
<div class="page">
4040
<div class="container header" style="background-color: #A288B3;">
4141
<p style="flex: 2;"><a target="_blank" href="https://github.com/elalish/manifold">Manifold</a>CAD
42-
&nbsp;&nbsp;<span class="top-edit blue">
43-
<button type="button" id="undo" class="top-icon undo squish"></button>
44-
<button type="button" id="redo" class="top-icon redo squish"></button>
45-
<button type="button" id="format" class="top-icon star squish"></button>
46-
<button type="button" id="share" class="top-icon share squish"></button>
47-
<a target="_blank" href="https://manifoldcad.org/docs/jsuser/" class="top-icon docs"></a>
42+
&nbsp;&nbsp;<span class="top-edit blue">
43+
<button type="button" id="undo" class="top-icon undo squish" title="Undo"></button>
44+
<button type="button" id="redo" class="top-icon redo squish" title="Redo"></button>
45+
<button type="button" id="format" class="top-icon star squish" title="Format Code"></button>
46+
<button type="button" id="share" class="top-icon share squish" title="Copy Shareable Link"></button>
47+
<a target="_blank" href="https://manifoldcad.org/docs/jsuser/" class="top-icon docs" title="Documentation"></a>
4848
</span>
49+
<span id="type-indicator" style="font-size: 14px; margin-left: 12px; font-weight: normal; opacity: 0.8;"></span>
4950
</p>
5051
<div class="margin" id="file-margin">
5152
<button type="button" id="file" class="blue item"><b class="uparrow"></b>&nbsp;&nbsp;<span

0 commit comments

Comments
 (0)