app
Component Widgets
Public Made by Adomby adom
Reusable component widgets for pinouts, thermal vias, molecule relationships, reviewed chip outlines and lightweight four-level LOD cache listings.
← Commit history
Publish 1.1.12
7 files changed
+17−3
SKILL.md+2@@ -199,3 +199,5 @@ Registered wiki widgets receive server-inlined manifest JSON. This does not auth For private wiki LODs, generate one lazy `*.frame.html` transport per level in the component repo. The transport contains that level's GLB bytes and posts an ArrayBuffer to its requesting parent. Record `transport.kind: wiki-sandbox-frame@1`, its path/hash/bytes and `sourceLevelSha256` in the level. It is navigated only after explicit enable and on demand for a selected level. The server's normal page authorization applies to that iframe navigation. The parent verifies the exact iframe window, random request nonce, expected GLB hash and byte count; times out after 12 seconds, aborts on disposal, removes the transport frame, and passes verified Uint8Array bytes directly to Babylon. Do not use a blob URL fetch where CSP disallows it. Never put an authentication ticket or session token in the transport. Opaque widgets also deny Web Storage. If access throws, use ephemeral document-local storage for canonical viewer preferences; never overwrite working user storage. Test against the real wiki CSP and private-file authorization separately from an unrestricted local harness. Preserve optional 3D behavior and small cached previews by default.++When enabling an inline preview, reveal the expanded viewer inside its existing work surface before starting offscreen observation or model loading. Test with the enable button near the bottom of a short viewport. Otherwise an otherwise-correct offscreen cleanup policy can immediately cancel the user's requested preview. Preserve the editor pane and OS foreground.
files/chip-thumbnail-widget.js+2@@ -158,6 +158,8 @@ async function mountLodPreview({host,manifest,resolveAsset,onState,signal}) { host.hidden=false;button.textContent='Turn off 3D preview';status.textContent='Loading super-low detail…';this._height(); const update=state=>{if(this._previewAbort!==abort)return;this._state.preview=state;this._state.glbRequests=state.glbRequests||0;this._previewActive=state.active;button.textContent=state.active?'Turn off 3D preview':'Turn on 3D preview';host.hidden=!state.active;status.textContent=state.active?`${state.level||'Loading'}${state.loading?' · loading '+state.wanted:''} · zoom to change detail`:'3D preview off'+(state.stopReason?' · '+state.stopReason:'');this._height();}; try{+ if(document.hidden)throw new Error('Activate this page before enabling 3D');+ await new Promise(resolve=>requestAnimationFrame(()=>{host.scrollIntoView({block:'center',behavior:'instant'});requestAnimationFrame(resolve);})); const module={mountLodPreview}; if(abort.signal.aborted){update({active:false,stopReason:'turned off'});return;} const controller=await module.mountLodPreview({host,manifest:d,resolveAsset:p=>this._url(p,src),onState:update,signal:abort.signal});if(this._previewAbort===abort)this._previewController=controller;else controller.dispose();
package.json+1−1@@ -2,7 +2,7 @@ "slug": "component-widgets", "title": "Component Widgets", "type": "app",- "version": "1.1.11",+ "version": "1.1.12", "description": "Reusable component-page widgets for pinouts, thermal vias, molecule relationships, reviewed chip outlines and image-first LOD caches with an optional zoom-driven 3D preview.", "license": "MIT", "dependencies": {},
page.json+6−2@@ -4,7 +4,7 @@ "type": "app", "title": "Component Widgets", "brief": "Reusable component widgets for pinouts, thermal vias, molecule relationships, reviewed chip outlines and lightweight four-level LOD cache listings.",- "version": "1.1.11",+ "version": "1.1.12", "visibility": { "public": true },@@ -60,6 +60,10 @@ "drop a pinout into a page", "reusable component widget", "cross-highlight pins on a page",+ "cached chip thumbnails",+ "reuse chip outline",+ "reviewed MPN placement",+ "chip artwork cache", "component LOD widget", "LOD listing", "LOD manifest",@@ -90,4 +94,4 @@ "hero", "readme" ]-}+}
skills/component-widgets/SKILL.md+2@@ -199,3 +199,5 @@ Registered wiki widgets receive server-inlined manifest JSON. This does not auth For private wiki LODs, generate one lazy `*.frame.html` transport per level in the component repo. The transport contains that level's GLB bytes and posts an ArrayBuffer to its requesting parent. Record `transport.kind: wiki-sandbox-frame@1`, its path/hash/bytes and `sourceLevelSha256` in the level. It is navigated only after explicit enable and on demand for a selected level. The server's normal page authorization applies to that iframe navigation. The parent verifies the exact iframe window, random request nonce, expected GLB hash and byte count; times out after 12 seconds, aborts on disposal, removes the transport frame, and passes verified Uint8Array bytes directly to Babylon. Do not use a blob URL fetch where CSP disallows it. Never put an authentication ticket or session token in the transport. Opaque widgets also deny Web Storage. If access throws, use ephemeral document-local storage for canonical viewer preferences; never overwrite working user storage. Test against the real wiki CSP and private-file authorization separately from an unrestricted local harness. Preserve optional 3D behavior and small cached previews by default.++When enabling an inline preview, reveal the expanded viewer inside its existing work surface before starting offscreen observation or model loading. Test with the enable button near the bottom of a short viewport. Otherwise an otherwise-correct offscreen cleanup policy can immediately cancel the user's requested preview. Preserve the editor pane and OS foreground.
skills/component-widgets/widgets/chip-thumbnail-widget.js+2@@ -158,6 +158,8 @@ async function mountLodPreview({host,manifest,resolveAsset,onState,signal}) { host.hidden=false;button.textContent='Turn off 3D preview';status.textContent='Loading super-low detail…';this._height(); const update=state=>{if(this._previewAbort!==abort)return;this._state.preview=state;this._state.glbRequests=state.glbRequests||0;this._previewActive=state.active;button.textContent=state.active?'Turn off 3D preview':'Turn on 3D preview';host.hidden=!state.active;status.textContent=state.active?`${state.level||'Loading'}${state.loading?' · loading '+state.wanted:''} · zoom to change detail`:'3D preview off'+(state.stopReason?' · '+state.stopReason:'');this._height();}; try{+ if(document.hidden)throw new Error('Activate this page before enabling 3D');+ await new Promise(resolve=>requestAnimationFrame(()=>{host.scrollIntoView({block:'center',behavior:'instant'});requestAnimationFrame(resolve);})); const module={mountLodPreview}; if(abort.signal.aborted){update({active:false,stopReason:'turned off'});return;} const controller=await module.mountLodPreview({host,manifest:d,resolveAsset:p=>this._url(p,src),onState:update,signal:abort.signal});if(this._previewAbort===abort)this._previewController=controller;else controller.dispose();
widgets/chip-thumbnail-widget.js+2@@ -158,6 +158,8 @@ async function mountLodPreview({host,manifest,resolveAsset,onState,signal}) { host.hidden=false;button.textContent='Turn off 3D preview';status.textContent='Loading super-low detail…';this._height(); const update=state=>{if(this._previewAbort!==abort)return;this._state.preview=state;this._state.glbRequests=state.glbRequests||0;this._previewActive=state.active;button.textContent=state.active?'Turn off 3D preview':'Turn on 3D preview';host.hidden=!state.active;status.textContent=state.active?`${state.level||'Loading'}${state.loading?' · loading '+state.wanted:''} · zoom to change detail`:'3D preview off'+(state.stopReason?' · '+state.stopReason:'');this._height();}; try{+ if(document.hidden)throw new Error('Activate this page before enabling 3D');+ await new Promise(resolve=>requestAnimationFrame(()=>{host.scrollIntoView({block:'center',behavior:'instant'});requestAnimationFrame(resolve);})); const module={mountLodPreview}; if(abort.signal.aborted){update({active:false,stopReason:'turned off'});return;} const controller=await module.mountLodPreview({host,manifest:d,resolveAsset:p=>this._url(p,src),onState:update,signal:abort.signal});if(this._previewAbort===abort)this._previewController=controller;else controller.dispose();