@popmelt.com/core 0.14.2 → 0.16.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 +97 -30
- package/codex-plugin/.codex-plugin/plugin.json +1 -1
- package/dist/adapter-three.d.mts +115 -0
- package/dist/adapter-three.mjs +1 -0
- package/dist/bridge-entry.mjs +68 -67
- package/dist/chunk-HS4EVUFK.mjs +2 -0
- package/dist/{chunk-LCXDL4VE.mjs → chunk-RYUNKCXK.mjs} +1 -1
- package/dist/cli.mjs +86 -85
- package/dist/image-adapter-D8L8QumX.d.mts +426 -0
- package/dist/index.d.mts +31 -190
- package/dist/index.mjs +64 -39
- package/dist/media.d.mts +14 -0
- package/dist/media.mjs +2 -0
- package/dist/plugin-astro.mjs +1 -1
- package/dist/plugin-vite.mjs +1 -1
- package/dist/server-F4EKHTYF.mjs +211 -0
- package/dist/server.d.mts +2 -1
- package/dist/server.mjs +69 -68
- package/package.json +16 -2
- package/dist/server-PHS6N6ZW.mjs +0 -210
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
var b=(r,e=0,t=1)=>Math.min(t,Math.max(e,r));function z(r){let{width:e,height:t}=r.rect,s=Math.max(1,r.naturalWidth),n=Math.max(1,r.naturalHeight),i=Math.min(e/s,t/n),o=Math.max(e/s,t/n);switch(r.objectFit){case"contain":return{width:s*i,height:n*i};case"cover":return{width:s*o,height:n*o};case"none":return{width:s,height:n};case"scale-down":{let a=Math.min(1,i);return{width:s*a,height:n*a}}default:return{width:e,height:t}}}function A(r,e){let t=r.trim().toLowerCase();if(t.endsWith("%")){let s=Number.parseFloat(t);return Number.isFinite(s)?e*(s/100):0}if(t.endsWith("px")){let s=Number.parseFloat(t);return Number.isFinite(s)?s:0}return t==="center"?e/2:t==="right"||t==="bottom"?e:0}function $(r,e,t){let s=r.objectPosition.trim().split(/\s+/),n=s[0]||"50%",i=s[1]||"50%";return{x:A(n,r.rect.width-e),y:A(i,r.rect.height-t)}}function x(r){let e=r.getBoundingClientRect();if(e.width<=0||e.height<=0||r.naturalWidth<=0||r.naturalHeight<=0)return null;let t=r.ownerDocument.defaultView?.getComputedStyle(r)??getComputedStyle(r),s={rect:e,naturalWidth:r.naturalWidth,naturalHeight:r.naturalHeight,objectFit:t.objectFit||"fill",objectPosition:t.objectPosition||"50% 50%"},n=z(s);return{layout:s,rendered:n,position:$(s,n.width,n.height)}}function j(r,e){let t=x(r);if(!t)return null;let{layout:s,rendered:n,position:i}=t;if(e.x<s.rect.left||e.x>s.rect.left+s.rect.width||e.y<s.rect.top||e.y>s.rect.top+s.rect.height)return null;let o=(e.x-s.rect.left-i.x)/n.width,a=(e.y-s.rect.top-i.y)/n.height;return o>=0&&o<=1&&a>=0&&a<=1?{x:o,y:a}:null}function T(r,e){let t=x(r);if(!t)return null;let{layout:s,rendered:n,position:i}=t,o=(e.left-s.rect.left-i.x)/n.width,a=(e.top-s.rect.top-i.y)/n.height,l=(e.left+e.width-s.rect.left-i.x)/n.width,c=(e.top+e.height-s.rect.top-i.y)/n.height,d=b(Math.min(o,l)),u=b(Math.min(a,c)),m=b(Math.max(o,l)),h=b(Math.max(a,c));return m<=d||h<=u?null:{left:d,top:u,width:m-d,height:h-u}}function M(r,e){if(![e.left,e.top,e.width,e.height].every(Number.isFinite))return null;let t=x(r);if(!t)return null;let{layout:s,rendered:n,position:i}=t,{rect:o}=s,a=o.left+i.x+b(e.left)*n.width,l=o.top+i.y+b(e.top)*n.height,c=o.left+i.x+b(e.left+Math.max(0,e.width))*n.width,d=o.top+i.y+b(e.top+Math.max(0,e.height))*n.height,u=Math.max(o.left,a),m=Math.max(o.top,l),h=Math.min(o.left+o.width,c),p=Math.min(o.top+o.height,d);return h<=u||p<=m?null:{left:u,top:m,width:h-u,height:p-m}}var D="popmelt:see:v1";function P(r){if(!r||typeof r!="object")return!1;let e=r;return["left","top","width","height"].every(t=>typeof e[t]=="number"&&Number.isFinite(e[t]))}function W(r){if(!r||typeof r!="object")return!1;let e=r;return typeof e.id=="string"&&typeof e.label=="string"&&typeof e.score=="number"&&(e.origin==="detected"||e.origin==="manual")&&P(e.box)&&(e.detectedBox===void 0||P(e.detectedBox))}function F(r){if(!r||typeof r!="object")return!1;let e=r;return typeof e.detectedLabel=="string"&&P(e.detectedBox)}function B(r){if(!r||typeof r!="object")return!1;let e=r;return e.schemaVersion===1&&typeof e.source=="string"&&typeof e.imageHash=="string"&&typeof e.inferenceKey=="string"&&typeof e.dedupeKey=="string"&&typeof e.updatedAt=="number"&&Array.isArray(e.subjects)&&e.subjects.every(W)&&(e.suppressions===void 0||Array.isArray(e.suppressions)&&e.suppressions.every(F))}function Y(r={}){let e=r.namespace??D,t=()=>r.storage??window.localStorage,s=a=>`${e}:${a}`,n=a=>`${s(a)}:history`,i=a=>{try{let l=t().getItem(s(a));if(!l)return null;let c=JSON.parse(l);return B(c)?c:null}catch{return null}},o=a=>{try{let l=t().getItem(n(a));if(!l)return[];let c=JSON.parse(l);return Array.isArray(c)?c.filter(B).slice(0,10):[]}catch{return[]}};return{load:i,save(a,l){let c=i(a);if(c&&c.imageHash!==l.imageHash){let d=o(a).filter(u=>u.imageHash!==c.imageHash||u.updatedAt!==c.updatedAt);t().setItem(n(a),JSON.stringify([c,...d].slice(0,10)))}t().setItem(s(a),JSON.stringify(l))},remove(a){t().removeItem(s(a)),t().removeItem(n(a))},loadHistory:o}}function G(){let r=new Map,e=new Map;return{load:t=>r.get(t)??null,save:(t,s)=>{let n=r.get(t);if(n&&n.imageHash!==s.imageHash){let i=e.get(t)??[];e.set(t,[n,...i.filter(o=>o.imageHash!==n.imageHash||o.updatedAt!==n.updatedAt)].slice(0,10))}r.set(t,s)},remove:t=>{r.delete(t),e.delete(t)},loadHistory:t=>e.get(t)??[]}}function K(r){return{label:r.label,score:r.score,box:{...r.box}}}var H="img";function L(r){let e=2166136261;for(let t=0;t<r.length;t+=1)e^=r.charCodeAt(t),e=Math.imul(e,16777619);return(e>>>0).toString(36)}function R(r){return new URL(g(r),r.ownerDocument.baseURI).href}async function N(r){let e=R(r);try{let t=await fetch(e,{cache:"force-cache",credentials:"same-origin"});if(!t.ok)throw new Error(`Unable to hash image (${t.status})`);let s=await t.arrayBuffer();if(!globalThis.crypto?.subtle)throw new Error("SubtleCrypto unavailable");let n=await globalThis.crypto.subtle.digest("SHA-256",s);return Array.from(new Uint8Array(n),i=>i.toString(16).padStart(2,"0")).join("")}catch{return`source:${L(e)}:${r.naturalWidth}x${r.naturalHeight}`}}function g(r){return r.currentSrc||r.src||r.getAttribute("src")||""}function U(r){return r.complete&&r.naturalWidth>0&&r.naturalHeight>0?Promise.resolve():new Promise((e,t)=>{let s=()=>{i(),e()},n=()=>{i(),t(new Error(`Unable to load image: ${g(r)}`))},i=()=>{r.removeEventListener("load",s),r.removeEventListener("error",n)};r.addEventListener("load",s,{once:!0}),r.addEventListener("error",n,{once:!0})})}function _(r,e){return{id:e.id,image:r,detection:K(e),detectedLabel:e.detectedLabel,detectedBox:e.detectedBox?{...e.detectedBox}:void 0,boundsOverridden:e.boundsOverridden,manual:e.origin==="manual"}}function q(r){return{id:r.id,label:r.detection.label,detectedLabel:r.detectedLabel,score:r.detection.score,box:{...r.detection.box},detectedBox:r.detectedBox?{...r.detectedBox}:void 0,origin:r.manual?"manual":"detected",boundsOverridden:r.boundsOverridden}}function V(r){return r.origin==="manual"||r.boundsOverridden===!0||!!(r.detectedLabel&&r.label!==r.detectedLabel)}function J(r,e){return e.x>=r.left&&e.x<=r.left+r.width&&e.y>=r.top&&e.y<=r.top+r.height}var O=class{constructor(e={}){this.options=e;this.surfaceKind="image";this.records=new Map;this.imageKeys=new Map;this.analyzedSources=new WeakMap;this.pending=new WeakMap;this.analysisMetadata=new WeakMap;this.suppressions=new WeakMap;this.writeChains=new WeakMap;this.pendingWrites=new Set;this.refreshQueued=!1;this.destroyed=!1;this.manualSequence=0;this.id=e.id??"see:image",this.readyPromise=this.refresh();let t=e.root??document;this.observer=e.observe!==!1&&typeof MutationObserver<"u"?new MutationObserver(()=>this.queueRefresh()):null,this.observer?.observe(t,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["src","srcset","sizes"]})}whenReady(){return this.readyPromise}listSubjects(){let e=[];for(let t of this.records.keys()){let s=this.resolve(t);s&&e.push(s)}return e}async refresh(){if(this.destroyed)return;let e=this.options.root??document,t=this.options.selector??H,s=new Set;e instanceof HTMLImageElement&&e.matches(t)&&s.add(e);for(let n of e.querySelectorAll(t))n instanceof HTMLImageElement&&s.add(n);for(let n of this.imageKeys.keys())(!s.has(n)||!n.isConnected)&&this.removeImage(n);if(this.options.recognition)for(let n of s)await this.analyze(n);else await Promise.all(Array.from(s,n=>this.analyze(n)))}hitTest(e){let t=null;for(let s of this.records.keys()){let n=this.resolve(s),i=this.records.get(s);if(!n||!i||!J(n.bounds,e))continue;let o=n.bounds.width*n.bounds.height;(!t||o<t.area||o===t.area&&i.detection.score>t.score)&&(t={subject:n,area:o,score:i.detection.score})}return t?.subject??null}resolve(e){let t=this.records.get(e);if(!t||!t.image.isConnected)return null;let s=M(t.image,t.detection.box);if(!s)return null;let n=t.image.getBoundingClientRect(),i=Math.round(t.detection.score*1e3)/1e3;return{key:e,label:t.detection.label,sourceElement:t.image,imageObject:this.imageObjectContext(t),bounds:s,surfaceBounds:{left:n.left,top:n.top,width:n.width,height:n.height},context:`${t.detection.label} ${t.manual?"labelled":"detected"} in ${t.image.alt||"image"}`,data:{kind:"image-object",label:t.detection.label,origin:t.manual?"manual":"detected",...t.detectedLabel?{detectedLabel:t.detectedLabel}:{},score:String(i),imageSrc:g(t.image)}}}imageObjectContext(e){let{image:t,detection:{box:s}}=e;return{src:g(t),alt:t.alt,width:t.naturalWidth,height:t.naturalHeight,normalizedBox:{x:s.left,y:s.top,width:s.width,height:s.height},box:{x:s.left*t.naturalWidth,y:s.top*t.naturalHeight,width:s.width*t.naturalWidth,height:s.height*t.naturalHeight}}}async captureSubject(e){let t=this.records.get(e);if(!t?.image.isConnected||!t.image.complete)return null;let{box:s}=this.imageObjectContext(t);if(s.width<=0||s.height<=0)return null;let n=Math.min(1,1024/Math.max(s.width,s.height)),i=document.createElement("canvas");i.width=Math.max(1,Math.round(s.width*n)),i.height=Math.max(1,Math.round(s.height*n));let o=i.getContext("2d");return o?(o.drawImage(t.image,s.x,s.y,s.width,s.height,0,0,i.width,i.height),new Promise((a,l)=>{try{i.toBlob(a,"image/webp",.95)}catch(c){l(c)}})):null}beginCreate(e){let t=this.matchingImages();for(let s=t.length-1;s>=0;s-=1){let n=t[s];if(!n)continue;let i=j(n,e);if(!i)continue;let o=g(n),a=this.imageIdentity(n,o),l=`manual:${this.newObjectId()}`,c=`${a}:${l}`,d={label:"object",score:1,box:{left:i.x,top:i.y,width:0,height:0}},u=!1,m=!1,h=()=>{if(m)return;m=!0,this.records.set(c,{id:l,image:n,detection:d,manual:!0});let p=this.imageKeys.get(n)??new Set;p.add(c),this.imageKeys.set(n,p)};return{key:c,update:p=>{if(u)return null;h();let y=this.clampedImagePoint(n,p);return y?(d.box={left:Math.min(i.x,y.x),top:Math.min(i.y,y.y),width:Math.abs(y.x-i.x),height:Math.abs(y.y-i.y)},this.resolve(c)):this.resolve(c)},commit:()=>u?null:(h(),this.persistImage(n),this.resolve(c)),cancel:()=>{u||(u=!0,m&&this.removeSubject(c))}}}return null}renameSubject(e,t){let s=this.records.get(e),n=t.trim();return!s||!n?null:(!s.manual&&!s.detectedLabel&&(s.detectedLabel=s.detection.label),s.detection.label=n,this.persistImage(s.image),this.resolve(e))}updateSubjectBounds(e,t){let s=this.records.get(e);if(!s)return null;let n=T(s.image,t);return n?(s.detection.box=n,s.boundsOverridden=!0,this.persistImage(s.image),this.resolve(e)):null}removeSubject(e){let t=this.records.get(e);if(!t)return;if(!t.manual){let n=this.suppressions.get(t.image)??[];n.push({detectedLabel:t.detectedLabel??t.detection.label,detectedBox:{...t.detectedBox??t.detection.box}}),this.suppressions.set(t.image,n)}this.records.delete(e);let s=this.imageKeys.get(t.image);s?.delete(e),s?.size===0&&this.imageKeys.delete(t.image),this.persistImage(t.image)}async destroy(){this.destroyed||(this.destroyed=!0,this.observer?.disconnect(),this.records.clear(),this.imageKeys.clear(),await Promise.allSettled(this.pendingWrites),await this.options.recognition?.dispose?.())}queueRefresh(){this.refreshQueued||this.destroyed||(this.refreshQueued=!0,queueMicrotask(()=>{this.refreshQueued=!1,this.readyPromise=this.refresh()}))}async analyze(e){let t=g(e);if(!t||this.analyzedSources.get(e)===t)return;let s=this.pending.get(e);if(s)return s.source===t?s.promise:(await s.promise,this.analyze(e));this.analyzedSources.has(e)&&this.removeImage(e);let n={source:t,promise:Promise.resolve()},i=(async()=>{try{if(await U(e),this.destroyed)return;let o=R(e),a=this.imageIdentity(e,t),l=`${this.id}:${a}`,c=this.options.recognition,d=this.options.store?await this.options.store.load(l):null;if(this.destroyed||g(e)!==t)return;let u=c?.cacheKey??d?.inferenceKey??"",m=c?.configurationKey??d?.dedupeKey??"",h=d?.source===o,p=!!(e.dataset.popmeltMediaId||e.dataset.popmeltSeeId),y=h||p;if(d&&y){let S=new Map(d.subjects.map(f=>[f.id,f]));for(let f of this.imageSubjects(e))S.set(f.id,f);this.replaceImageRecords(e,a,[...S.values()]),this.suppressions.set(e,[...d.suppressions??[]]),this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:d.imageHash,inferenceKey:d.inferenceKey,dedupeKey:d.dedupeKey})}if(this.options.hydrateOnly){this.analyzedSources.set(e,t);return}let I=this.options.store?await(this.options.imageHasher??N)(e):"ephemeral";if(this.destroyed||g(e)!==t)return;if(!!(d&&y&&d.imageHash===I&&(!c||d.inferenceKey===u&&d.dedupeKey===m))){this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:I,inferenceKey:u,dedupeKey:m}),this.analyzedSources.set(e,t),await this.saveImage(e);return}let v=y&&d?.imageHash===I;if(d&&!v){let S=new Set(d.subjects.map(w=>w.id)),f=d.subjects.filter(V);this.replaceImageRecords(e,a,[...f,...this.imageSubjects(e).filter(w=>!S.has(w.id))]),this.suppressions.set(e,[])}if(this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:I,inferenceKey:v?d.inferenceKey:"",dedupeKey:v?d.dedupeKey:""}),!c){this.analyzedSources.set(e,t),await this.saveImage(e);return}let C=await c.detect(e);if(this.destroyed||g(e)!==t)return;let E=this.suppressions.get(e)??[],k=c.reconcile(C,this.imageSubjects(e),E);this.replaceImageRecords(e,a,k),this.suppressions.set(e,[...E]),this.analysisMetadata.set(e,{storeKey:l,source:o,imageHash:I,inferenceKey:u,dedupeKey:m}),this.analyzedSources.set(e,t),await this.saveImage(e)}catch(o){this.options.onError?.(o,e)}finally{this.pending.get(e)===n&&this.pending.delete(e)}})();return n.promise=i,this.pending.set(e,n),i}replaceImageRecords(e,t,s){this.removeImage(e);let n=new Set;for(let i of s){let o=`${t}:${i.id}`;n.add(o),this.records.set(o,_(e,i))}this.imageKeys.set(e,n)}imageIdentity(e,t){if(e.dataset.popmeltMediaId)return e.dataset.popmeltMediaId;if(e.dataset.popmeltSeeId)return e.dataset.popmeltSeeId;let s=new URL(t,e.ownerDocument.baseURI).href,n=this.options.root??e.ownerDocument,i=this.options.selector??H,o=Array.from(n.querySelectorAll(i)).filter(l=>g(l)===t),a=Math.max(0,o.indexOf(e));return`${L(s)}:${a}`}matchingImages(){let e=this.options.root??document,t=this.options.selector??H,s=[];e instanceof HTMLImageElement&&e.matches(t)&&s.push(e);for(let n of e.querySelectorAll(t))n instanceof HTMLImageElement&&s.push(n);return s}clampedImagePoint(e,t){let s=M(e,{left:0,top:0,width:1,height:1});return s?j(e,{x:Math.max(s.left,Math.min(s.left+s.width,t.x)),y:Math.max(s.top,Math.min(s.top+s.height,t.y))}):null}newObjectId(){let e=globalThis.crypto?.randomUUID?.();return e||L(`${Date.now()}:${this.manualSequence++}:${Math.random().toString(36)}`)}persistImage(e){let t=this.persistencePayload(e);if(!t)return Promise.resolve();let n=(this.writeChains.get(e)??Promise.resolve()).catch(()=>{}).then(()=>t.store.save(t.key,t.analysis)).catch(i=>{this.options.onError?.(i,e)});return this.writeChains.set(e,n),this.pendingWrites.add(n),n.finally(()=>this.pendingWrites.delete(n)),n}async saveImage(e){await this.persistImage(e)}imageSubjects(e){return Array.from(this.imageKeys.get(e)??[]).map(t=>this.records.get(t)).filter(t=>!!t).map(q)}persistencePayload(e){let t=this.options.store,s=this.analysisMetadata.get(e);if(!t||!s)return null;let n=this.imageSubjects(e),i={schemaVersion:1,source:s.source,imageHash:s.imageHash,inferenceKey:s.inferenceKey,dedupeKey:s.dedupeKey,subjects:n,suppressions:this.suppressions.get(e)??[],updatedAt:Date.now()};return{store:t,key:s.storeKey,analysis:i}}removeImage(e){for(let t of this.imageKeys.get(e)??[])this.records.delete(t);this.imageKeys.delete(e),this.analyzedSources.delete(e),this.analysisMetadata.delete(e),this.suppressions.delete(e)}};function se(r={}){return new O(r)}export{j as a,T as b,M as c,Y as d,G as e,O as f,se as g};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as p}from"./chunk-NOHXTT24.mjs";import{request as c}from"http";function u(){let e=process.env.POPMELT_BRIDGE_URL;if(!e)return null;try{let t=new URL(e);return{port:t.port?Number.parseInt(t.port,10):null,projectId:process.env.POPMELT_PROJECT_ID||null,leaseEligible:!1}}catch{return null}}async function h(e,t,i){let r=u();if(e?.bridge===!1||r)return r??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:o}=await import("./server-
|
|
1
|
+
import{a as p}from"./chunk-NOHXTT24.mjs";import{request as c}from"http";function u(){let e=process.env.POPMELT_BRIDGE_URL;if(!e)return null;try{let t=new URL(e);return{port:t.port?Number.parseInt(t.port,10):null,projectId:process.env.POPMELT_PROJECT_ID||null,leaseEligible:!1}}catch{return null}}async function h(e,t,i){let r=u();if(e?.bridge===!1||r)return r??{port:null,projectId:null,leaseEligible:!1};try{let{startPopmelt:o}=await import("./server-F4EKHTYF.mjs"),n=t.config?.server?.host,l=n===!0?"0.0.0.0":n||"localhost",s=t.config?.server?.port??i,d=`http://${l==="0.0.0.0"?"localhost":l}:${s}`,a=await o({port:e?.port,projectRoot:e?.projectRoot,devOrigin:d,force:!0,detached:!0,manageLease:!1});return console.log(`[popmelt] bridge ready at http://localhost:${a.port}`),{port:a.port,projectId:a.projectId,leaseEligible:!0}}catch(o){let n=o instanceof Error?o.message:String(o);return console.warn("[popmelt] bridge failed to start:",n),{port:null,projectId:null,leaseEligible:!1}}}async function v(e,t,i=fetch){if(!e.leaseEligible||e.port===null)return null;let r=await p({port:e.port,projectId:e.projectId},i);if(!r)return null;let o=()=>{n()},n=async()=>{process.removeListener("beforeExit",o),await r.release()};return process.once("beforeExit",o),t.httpServer?.once("close",()=>{n()}),{id:r.id,release:n}}function g(e,t,i){if(i.port===null)return null;let r=new URL(t,"http://popmelt.local");if(r.pathname!==`${e}/status`)return null;let o=new URL("/status",`http://localhost:${i.port}`);return r.searchParams.forEach((n,l)=>o.searchParams.append(l,n)),i.projectId&&o.searchParams.set("projectId",i.projectId),o}function b(e,t){return(i,r,o)=>{let n=g(e,i.url||"",t());if(!n)return o();let l=c(n,{method:i.method,headers:{...i.headers,host:n.host}},s=>{r.writeHead(s.statusCode||502,s.headers),s.pipe(r)});l.on("error",()=>{r.writeHead(502,{"Content-Type":"text/plain"}),r.end(`Popmelt bridge not running on port ${t().port}`)}),i.pipe(l)}}function P(e){let t=e.port===null?null:`http://localhost:${e.port}`;return`window.__POPMELT_BRIDGE_URL__=${JSON.stringify(t)};window.__POPMELT_PROJECT_ID__=${JSON.stringify(e.projectId)};`}export{h as a,v as b,b as c,P as d};
|