shaders 2.5.120 → 2.5.122

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.
@@ -163,25 +163,17 @@ const componentDefinition = {
163
163
  const animTime = createAnimatedTime(params, uniforms.speed);
164
164
  const renderParticle = Fn(([uv$2]) => {
165
165
  const rootUV = floor(uv$2);
166
- const localPos = fract(uv$2);
167
- let minDist = getParticleDistance(uv$2, rootUV, uniforms.randomness.uniform);
166
+ const randomness = uniforms.randomness.uniform;
167
+ const dCenter = getParticleDistance(uv$2, rootUV, randomness);
168
+ const dLeft = getParticleDistance(uv$2, rootUV.add(vec2(-1, 0)), randomness);
169
+ const dRight = getParticleDistance(uv$2, rootUV.add(vec2(1, 0)), randomness);
170
+ const dTop = getParticleDistance(uv$2, rootUV.add(vec2(0, -1)), randomness);
171
+ const dBottom = getParticleDistance(uv$2, rootUV.add(vec2(0, 1)), randomness);
172
+ const minDist = min(min(min(min(dCenter, dLeft), dRight), dTop), dBottom);
168
173
  const softness = uniforms.particleSoftness.uniform;
169
174
  const scaledSize = uniforms.particleSize.uniform.mul(.01);
170
- const outerRadius = scaledSize.mul(.6).add(softness.mul(scaledSize.mul(2.4)));
171
- const needsNeighbors = outerRadius.greaterThan(.35);
172
- const nearLeft = localPos.x.lessThan(.4);
173
- const nearRight = localPos.x.greaterThan(.6);
174
- const nearTop = localPos.y.lessThan(.4);
175
- const nearBottom = localPos.y.greaterThan(.6);
176
- const checkLeft = needsNeighbors.and(nearLeft);
177
- const checkRight = needsNeighbors.and(nearRight);
178
- const checkTop = needsNeighbors.and(nearTop);
179
- const checkBottom = needsNeighbors.and(nearBottom);
180
- minDist = checkLeft.select(min(minDist, getParticleDistance(uv$2, rootUV.add(vec2(-1, 0)), uniforms.randomness.uniform)), minDist);
181
- minDist = checkRight.select(min(minDist, getParticleDistance(uv$2, rootUV.add(vec2(1, 0)), uniforms.randomness.uniform)), minDist);
182
- minDist = checkTop.select(min(minDist, getParticleDistance(uv$2, rootUV.add(vec2(0, -1)), uniforms.randomness.uniform)), minDist);
183
- minDist = checkBottom.select(min(minDist, getParticleDistance(uv$2, rootUV.add(vec2(0, 1)), uniforms.randomness.uniform)), minDist);
184
- const baseIntensity = smoothstep(scaledSize.mul(.6), outerRadius, minDist).oneMinus();
175
+ const innerRadius = scaledSize.mul(.6);
176
+ const baseIntensity = smoothstep(innerRadius, innerRadius.add(softness.mul(scaledSize.mul(2.4))), minDist).oneMinus();
185
177
  const twinkleIntensity = uniforms.twinkle.uniform;
186
178
  const particlePhase = rootUV.x.mul(12.9898).add(rootUV.y.mul(78.233)).sin().mul(43758.5453).fract();
187
179
  const twinkleValue = sin(time.mul(2).add(particlePhase.mul(6.28318))).mul(.5).add(.5);
@@ -42,7 +42,7 @@ import "./Ellipse-sWhNvW9-.js";
42
42
  import "./Emboss-DGaubb9x.js";
43
43
  import "./FallingLines-DqIZ8wTH.js";
44
44
  import "./FilmGrain-Dbw02Jz9.js";
45
- import "./FloatingParticles-C4sLwGyT.js";
45
+ import "./FloatingParticles-DKoG78j0.js";
46
46
  import "./Flower-BbRNrXIa.js";
47
47
  import "./FlowField-D3CAHBBG.js";
48
48
  import "./FlowingGradient-BRQ_K-k3.js";
@@ -122,7 +122,7 @@ import "./Weave-DJ4s3Gwc.js";
122
122
  import "./WebcamTexture-9Td8qQWm.js";
123
123
  import "./WorleyNoise-CWytDfGH.js";
124
124
  import "./ZoomBlur-DWFQVFMK.js";
125
- import { t as getAllShaders } from "./shaderRegistry-CO5SCxc6.js";
125
+ import { t as getAllShaders } from "./shaderRegistry-BoqhBfun.js";
126
126
  import { Material, Mesh, MeshBasicNodeMaterial, OrthographicCamera, PlaneGeometry, SRGBColorSpace, Scene, Vector2, WebGPURenderer } from "three/webgpu";
127
127
  import { WebGLRenderer } from "three";
128
128
  import { PI, abs, add, atan, clamp, convertToTexture, cos, div, dot, float, fract, max, min, mix, mul, pow, screenUV, sign, sin, smoothstep, sqrt, step, sub, time, uniform, uv, vec2, vec3, vec4 } from "three/tsl";
@@ -768,6 +768,7 @@ function shaderRenderer() {
768
768
  let isUpdatingMaterial = false;
769
769
  let pendingNodeRemoval = false;
770
770
  let globalEventUnregister = null;
771
+ let canvasContextLossUnregister = null;
771
772
  let unloadHandler = null;
772
773
  let windowResizeHandler = null;
773
774
  let cachedMaxTextureDim = 8192;
@@ -780,6 +781,22 @@ function shaderRenderer() {
780
781
  let onReadyCallback = null;
781
782
  let hasEmittedReady = false;
782
783
  let firstRenderPending = false;
784
+ let onDeviceLostCallback = null;
785
+ let deviceLostFired = false;
786
+ const fireDeviceLost = (reason) => {
787
+ if (deviceLostFired) return;
788
+ deviceLostFired = true;
789
+ try {
790
+ stopAnimation();
791
+ } catch {}
792
+ if (onDeviceLostCallback) queueMicrotask(() => {
793
+ try {
794
+ onDeviceLostCallback?.(reason);
795
+ } catch (e) {
796
+ console.error("[Shaders] onDeviceLost callback threw:", e);
797
+ }
798
+ });
799
+ };
783
800
  let materialUpdateBatchRAF = null;
784
801
  let lastComposedNodes = /* @__PURE__ */ new Set();
785
802
  let activeRTTNodes = /* @__PURE__ */ new Set();
@@ -2145,6 +2162,14 @@ function shaderRenderer() {
2145
2162
  stencil: true,
2146
2163
  powerPreference: "high-performance"
2147
2164
  });
2165
+ const wglLost = (e) => {
2166
+ e.preventDefault();
2167
+ fireDeviceLost("webglcontextlost");
2168
+ };
2169
+ canvas.addEventListener("webglcontextlost", wglLost, false);
2170
+ canvasContextLossUnregister = () => {
2171
+ canvas.removeEventListener("webglcontextlost", wglLost, false);
2172
+ };
2148
2173
  } else try {
2149
2174
  renderer = new WebGPURenderer({
2150
2175
  canvas,
@@ -2159,6 +2184,15 @@ function shaderRenderer() {
2159
2184
  });
2160
2185
  else await renderer.init();
2161
2186
  if (localAbortController.signal.aborted) return;
2187
+ try {
2188
+ const device = renderer.backend?.device;
2189
+ if (device?.lost && typeof device.lost.then === "function") device.lost.then((info) => {
2190
+ if (info?.reason === "destroyed") return;
2191
+ fireDeviceLost(info?.message || info?.reason || "unknown");
2192
+ }).catch(() => {});
2193
+ } catch (hookErr) {
2194
+ console.warn("[Shaders] could not attach WebGPU device.lost handler", hookErr);
2195
+ }
2162
2196
  } catch (e) {
2163
2197
  if (localAbortController.signal.aborted) return;
2164
2198
  console.warn("[Shaders] WebGPU initialization failed, falling back to WebGL:", e);
@@ -2174,6 +2208,14 @@ function shaderRenderer() {
2174
2208
  if (context) webglOptions.context = context;
2175
2209
  renderer = new WebGLRenderer(webglOptions);
2176
2210
  if (localAbortController.signal.aborted) return;
2211
+ const wglLost = (e$1) => {
2212
+ e$1.preventDefault();
2213
+ fireDeviceLost("webglcontextlost");
2214
+ };
2215
+ canvas.addEventListener("webglcontextlost", wglLost, false);
2216
+ canvasContextLossUnregister = () => {
2217
+ canvas.removeEventListener("webglcontextlost", wglLost, false);
2218
+ };
2177
2219
  } catch (webglError) {
2178
2220
  if (localAbortController.signal.aborted) return;
2179
2221
  console.error("[Shaders] Both WebGPU and WebGL initialization failed:", webglError);
@@ -2266,6 +2308,10 @@ function shaderRenderer() {
2266
2308
  globalEventUnregister();
2267
2309
  globalEventUnregister = null;
2268
2310
  }
2311
+ if (canvasContextLossUnregister) {
2312
+ canvasContextLossUnregister();
2313
+ canvasContextLossUnregister = null;
2314
+ }
2269
2315
  if (canvasElement) {
2270
2316
  canvasElement.removeEventListener("mousedown", canvasMouseDownHandler);
2271
2317
  canvasElement.removeEventListener("touchstart", canvasTouchStartHandler);
@@ -2331,6 +2377,8 @@ function shaderRenderer() {
2331
2377
  onReadyCallback = null;
2332
2378
  hasEmittedReady = false;
2333
2379
  firstRenderPending = false;
2380
+ onDeviceLostCallback = null;
2381
+ deviceLostFired = false;
2334
2382
  };
2335
2383
  const getRendererType = () => {
2336
2384
  if (!renderer) return null;
@@ -2363,6 +2411,9 @@ function shaderRenderer() {
2363
2411
  setOnReady: (callback) => {
2364
2412
  onReadyCallback = callback;
2365
2413
  },
2414
+ setOnDeviceLost: (callback) => {
2415
+ onDeviceLostCallback = callback;
2416
+ },
2366
2417
  __testing: {
2367
2418
  needsTransformation,
2368
2419
  findChildNodes,
@@ -42,7 +42,7 @@ import "./Ellipse-sWhNvW9-.js";
42
42
  import "./Emboss-DGaubb9x.js";
43
43
  import "./FallingLines-DqIZ8wTH.js";
44
44
  import "./FilmGrain-Dbw02Jz9.js";
45
- import "./FloatingParticles-C4sLwGyT.js";
45
+ import "./FloatingParticles-DKoG78j0.js";
46
46
  import "./Flower-BbRNrXIa.js";
47
47
  import "./FlowField-D3CAHBBG.js";
48
48
  import "./FlowingGradient-BRQ_K-k3.js";
@@ -122,5 +122,5 @@ import "./Weave-DJ4s3Gwc.js";
122
122
  import "./WebcamTexture-9Td8qQWm.js";
123
123
  import "./WorleyNoise-CWytDfGH.js";
124
124
  import "./ZoomBlur-DWFQVFMK.js";
125
- import { a as shaderRegistry, i as getShadersByCategory, n as getShaderByName, r as getShaderCategories, t as getAllShaders } from "./shaderRegistry-CO5SCxc6.js";
125
+ import { a as shaderRegistry, i as getShadersByCategory, n as getShaderByName, r as getShaderCategories, t as getAllShaders } from "./shaderRegistry-BoqhBfun.js";
126
126
  export { getAllShaders, getShaderByName, getShaderCategories, getShadersByCategory, shaderRegistry };
@@ -198,6 +198,7 @@ export declare function shaderRenderer(): {
198
198
  getInternalRenderer: () => WebGPURenderer | WebGLRenderer;
199
199
  setForceFullFrameRate: (enabled: boolean) => boolean;
200
200
  setOnReady: (callback: (() => void) | null) => void;
201
+ setOnDeviceLost: (callback: ((reason: string) => void) | null) => void;
201
202
  __testing: {
202
203
  needsTransformation: (transform: import('./types').TransformConfig | undefined) => boolean;
203
204
  findChildNodes: (parentId: string) => NodeInfo[];
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,IAAI,EAMT,cAAc,EACjB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAC,aAAa,EAAC,MAAM,OAAO,CAAA;AAInC,OAAO,EAAoB,eAAe,EAAE,mBAAmB,EAAE,UAAU,EAA8D,YAAY,EAAE,cAAc,EAAE,cAAc,EAAqB,WAAW,EAAC,MAAM,SAAS,CAAA;AACrO,OAAO,EAAqB,gBAAgB,EAAC,MAAM,sBAAsB,CAAA;AAMzE;;GAEG;AACH,UAAU,QAAQ;IAEd;;;OAGG;IACH,EAAE,EAAE,MAAM,CAAA;IAEV;;OAEG;IACH,aAAa,EAAE,MAAM,CAAA;IAErB;;OAEG;IACH,gBAAgB,EAAE,mBAAmB,CAAC,cAAc,CAAC,CAAA;IAErD;;OAEG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAEvB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAA;IAEpB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAA;IAEtB;;OAEG;IACH,cAAc,EAAE,GAAG,CAAA;IAEnB;;OAEG;IACH,QAAQ,EAAE,YAAY,CAAA;IAEtB;;OAEG;IACH,QAAQ,EAAE,WAAW,CAAA;IAErB;;;OAGG;IACH,gBAAgB,EAAE,eAAe,EAAE,CAAA;IAEnC;;;OAGG;IACH,qBAAqB,EAAE,cAAc,EAAE,CAAA;IAEvC;;;OAGG;IACH,oBAAoB,EAAE,cAAc,EAAE,CAAA;IAEtC;;;OAGG;IACH,eAAe,EAAE,cAAc,EAAE,CAAA;IAEjC;;OAEG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAA;IAE7B;;;OAGG;IACH,iBAAiB,CAAC,EAAE;QAChB,OAAO,EAAE,GAAG,CAAA;QACZ,OAAO,EAAE,GAAG,CAAA;QACZ,QAAQ,EAAE,GAAG,CAAA;QACb,KAAK,EAAE,GAAG,CAAA;QACV,OAAO,EAAE,GAAG,CAAA;QACZ,OAAO,EAAE,GAAG,CAAA;QACZ,KAAK,EAAE,GAAG,CAAA;QACV,WAAW,EAAE,GAAG,CAAA;KACnB,CAAA;IAED;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAE5B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,WAAW,KAAK,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEjE;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QACzB,QAAQ,EAAE,GAAG,CAAA;QACb,QAAQ,EAAE,GAAG,CAAA;QACb,SAAS,EAAE,GAAG,CAAA;QACd,SAAS,EAAE,GAAG,CAAA;QACd,KAAK,EAAE,GAAG,CAAA;QACV,aAAa,CAAC,EAAE,GAAG,CAAA;QACnB,OAAO,CAAC,EAAE,UAAU,CAAA;KACvB,CAAC,CAAA;IAEF;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAC9B,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,EAAE,MAAM,CAAA;QACjB,SAAS,EAAE,MAAM,CAAA;QACjB,eAAe,EAAE,GAAG,CAAA;KACvB,CAAC,CAAA;IAEF;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAC9B,eAAe,EAAE,GAAG,CAAA;KACvB,CAAC,CAAA;IAEF;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,CAAA;IAEtC;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEpC;;;OAGG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,GAAG,EAAE,GAAG,IAAI,CAAA;IAE/C,wFAAwF;IACxF,WAAW,CAAC,EAAE,OAAO,CAAA;CAExB;AAED;;GAEG;AACH,UAAU,YAAY;IAClB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;IAC5B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED;;GAEG;AACH,UAAU,iBAAiB;IACvB,MAAM,EAAE,iBAAiB,CAAA;IACzB;mGAC+F;IAC/F,YAAY,CAAC,EAAE,WAAW,CAAA;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,UAAU,CAAC,EAAE,WAAW,GAAG,MAAM,CAAC;IAClC,OAAO,CAAC,EAAE,qBAAqB,GAAG,sBAAsB,CAAA;IACxD,GAAG,CAAC,EAAE;QACF,MAAM,EAAE,SAAS,CAAA;QACjB,OAAO,EAAE,UAAU,CAAA;KACtB,CAAA;IACD,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;4BAEwB;IACxB,cAAc,CAAC,EAAE,OAAO,CAAA;CAC3B;AAiHD;;GAEG;AACH,wBAAgB,cAAc;wLAq/EG,iBAAiB;;uBArnCpB,MAAM,oBAAoB,mBAAmB,CAAC,cAAc,CAAC,GAAG,IAAI,YAAY,MAAM,GAAG,IAAI,YAAY,YAAY,GAAG,IAAI,aAAY,WAAW,wBAA6B,mBAAmB,cAAc,iBAAiB,KAAG,IAAI;qBA6b3O,MAAM,KAAG,IAAI;iCA3RD,MAAM,eAAe,MAAM,SAAS,GAAG,KAAG,IAAI;iCA8D9C,MAAM,YAAY,OAAO,CAAC,YAAY,CAAC,KAAG,IAAI;;oBAo1C9D,MAAM,UAAU,MAAM;0BA5oBf,IAAI;yBAyBL,IAAI;yBApPE,OAAO,CAAC,IAAI,CAAC;+BA0Mb,gBAAgB;;eAqqBmB,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC;;2BArBpE,QAAQ,GAAG,OAAO,GAAG,IAAI;;qCAwBhB,OAAO,KAAG,OAAO;2BAK3B,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI;gCAGd,CAAC,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI;;;mCA79E/B,MAAM,KAAG,QAAQ,EAAE;oCA+CzC,IAAI,YACF,QAAQ,UACV,MAAM,kBACE,GAAG,CAAC,MAAM,CAAC,gBACb,IAAI,KACnB,IAAI;0CA0VK,IAAI,YACF,QAAQ,KACnB,IAAI;;;;EA2lEV"}
@@ -35,7 +35,7 @@ import { n as componentDefinition$33 } from "./Ellipse-sWhNvW9-.js";
35
35
  import { n as componentDefinition$34 } from "./Emboss-DGaubb9x.js";
36
36
  import { n as componentDefinition$35 } from "./FallingLines-DqIZ8wTH.js";
37
37
  import { n as componentDefinition$36 } from "./FilmGrain-Dbw02Jz9.js";
38
- import { n as componentDefinition$37 } from "./FloatingParticles-C4sLwGyT.js";
38
+ import { n as componentDefinition$37 } from "./FloatingParticles-DKoG78j0.js";
39
39
  import { n as componentDefinition$38 } from "./Flower-BbRNrXIa.js";
40
40
  import { n as componentDefinition$39 } from "./FlowField-D3CAHBBG.js";
41
41
  import { n as componentDefinition$40 } from "./FlowingGradient-BRQ_K-k3.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shaders/FloatingParticles/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAqB,MAAM,iBAAiB,CAAA;AAIvE,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAA;AAkClE,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;CAC1B;AAED,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,cAAc,CAyNnE,CAAA;AAED,eAAe,mBAAmB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/shaders/FloatingParticles/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,mBAAmB,EAAqB,MAAM,iBAAiB,CAAA;AAIvE,OAAO,EAAC,cAAc,EAAC,MAAM,qCAAqC,CAAA;AAkClE,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;IACpB,gBAAgB,EAAE,MAAM,CAAA;IACxB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC,CAAA;IACnD,aAAa,EAAE,MAAM,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;CAC1B;AAED,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,cAAc,CAuMnE,CAAA;AAED,eAAe,mBAAmB,CAAA"}
@@ -1,4 +1,4 @@
1
1
  import "../../transformations-CJcUeZIC.js";
2
2
  import "../../time-DUqSFWvT.js";
3
- import { n as componentDefinition, t as FloatingParticles_default } from "../../FloatingParticles-C4sLwGyT.js";
3
+ import { n as componentDefinition, t as FloatingParticles_default } from "../../FloatingParticles-DKoG78j0.js";
4
4
  export { componentDefinition, FloatingParticles_default as default };
@@ -1 +1 @@
1
- {"version":3,"file":"createShader.d.ts","sourceRoot":"","sources":["../src/createShader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,cAAc,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAqB5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,cAAc,CAAC,CAiRzB"}
1
+ {"version":3,"file":"createShader.d.ts","sourceRoot":"","sources":["../src/createShader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAmB,MAAM,cAAc,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AAgC5D;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,YAAY,EACpB,OAAO,CAAC,EAAE,aAAa,GACtB,OAAO,CAAC,cAAc,CAAC,CA2WzB"}
@@ -16,13 +16,10 @@ var METADATA_PROPS = new Set([
16
16
  "maskType"
17
17
  ]);
18
18
  async function createShader(canvas, preset, options) {
19
- const renderer = shaderRenderer();
20
- if (options?.onReady) renderer.setOnReady(options.onReady);
21
19
  const componentRegistry = /* @__PURE__ */ new Map();
22
20
  getAllShaders().forEach((shader) => {
23
21
  componentRegistry.set(shader.definition.name, shader.definition);
24
22
  });
25
- const nodeEntryMap = /* @__PURE__ */ new Map();
26
23
  if (!canvas.style.width || !canvas.style.height) {
27
24
  const rect = canvas.getBoundingClientRect();
28
25
  const w = rect.width > 0 ? rect.width : canvas.width;
@@ -30,32 +27,21 @@ async function createShader(canvas, preset, options) {
30
27
  if (w > 0 && !canvas.style.width) canvas.style.width = `${w}px`;
31
28
  if (h > 0 && !canvas.style.height) canvas.style.height = `${h}px`;
32
29
  }
33
- await renderer.initialize({
34
- canvas,
35
- resizeTarget: canvas,
36
- enablePerformanceTracking: options?.enablePerformanceTracking || false,
37
- colorSpace: options?.colorSpace,
38
- observeElement: options?.observeElement,
39
- gpu: options?.gpu
40
- });
41
- const rootId = "shader-root";
42
- renderer.registerNode(rootId, ({ childNode }) => childNode || vec4(0, 0, 0, 0), null, null, {}, void 0);
43
- preset.components.forEach((component, index) => {
44
- registerComponent(component, rootId, index);
45
- });
46
- let telemetryCollector = null;
47
- let telemetryStartTimeout = null;
48
- if (isExternalUser()) {
49
- const checkRendering = () => {
50
- if (renderer.getPerformanceStats().fps > 0) {
51
- telemetryCollector = startTelemetry(renderer, "2.5.120", options?.disableTelemetry || false, false);
52
- if (telemetryCollector) telemetryCollector.start();
53
- telemetryStartTimeout = null;
54
- } else telemetryStartTimeout = setTimeout(checkRendering, 500);
30
+ function cloneComponent(c) {
31
+ return {
32
+ ...c,
33
+ props: c.props ? { ...c.props } : void 0,
34
+ children: c.children?.map(cloneComponent)
55
35
  };
56
- telemetryStartTimeout = setTimeout(checkRendering, 500);
57
36
  }
58
- function registerComponent(component, parentId, renderOrder) {
37
+ const livePreset = {
38
+ ...preset,
39
+ components: preset.components.map(cloneComponent)
40
+ };
41
+ let current = null;
42
+ let destroyed = false;
43
+ let rebuilding = false;
44
+ function registerComponent(renderer, nodeEntryMap, component, parentId, renderOrder) {
59
45
  const componentDef = componentRegistry.get(component.type);
60
46
  if (!componentDef) {
61
47
  console.warn(`[createShader] Unknown component type: ${component.type}`);
@@ -99,33 +85,134 @@ async function createShader(canvas, preset, options) {
99
85
  currentMaps: { ...mapsFromProps }
100
86
  });
101
87
  component.children?.forEach((child, index) => {
102
- registerComponent(child, nodeId, index);
88
+ registerComponent(renderer, nodeEntryMap, child, nodeId, index);
89
+ });
90
+ }
91
+ async function build() {
92
+ const renderer = shaderRenderer();
93
+ const nodeEntryMap = /* @__PURE__ */ new Map();
94
+ if (options?.onReady) renderer.setOnReady(options.onReady);
95
+ await renderer.initialize({
96
+ canvas,
97
+ resizeTarget: canvas,
98
+ enablePerformanceTracking: options?.enablePerformanceTracking || false,
99
+ colorSpace: options?.colorSpace,
100
+ observeElement: options?.observeElement,
101
+ gpu: options?.gpu
102
+ });
103
+ const state = {
104
+ renderer,
105
+ nodeEntryMap,
106
+ telemetryCollector: null,
107
+ telemetryStartTimeout: null
108
+ };
109
+ renderer.setOnDeviceLost((reason) => {
110
+ if (destroyed || rebuilding) return;
111
+ if (current !== null && current !== state) return;
112
+ rebuilding = true;
113
+ try {
114
+ options?.onError?.(reason);
115
+ } catch (e) {
116
+ console.error("[createShader] onError callback threw:", e);
117
+ }
118
+ (async () => {
119
+ try {
120
+ teardownState(state);
121
+ current = null;
122
+ if (destroyed) return;
123
+ const next = await build();
124
+ if (destroyed) {
125
+ teardownState(next);
126
+ return;
127
+ }
128
+ current = next;
129
+ } catch (rebuildErr) {
130
+ console.error("[createShader] rebuild after device loss failed:", rebuildErr);
131
+ try {
132
+ options?.onError?.("rebuild_failed");
133
+ } catch {}
134
+ } finally {
135
+ rebuilding = false;
136
+ }
137
+ })();
103
138
  });
139
+ const rootId = "shader-root";
140
+ renderer.registerNode(rootId, ({ childNode }) => childNode || vec4(0, 0, 0, 0), null, null, {}, void 0);
141
+ livePreset.components.forEach((component, index) => {
142
+ registerComponent(renderer, nodeEntryMap, component, rootId, index);
143
+ });
144
+ if (isExternalUser()) {
145
+ const checkRendering = () => {
146
+ if (destroyed || current !== state) {
147
+ state.telemetryStartTimeout = null;
148
+ return;
149
+ }
150
+ if (renderer.getPerformanceStats().fps > 0) {
151
+ state.telemetryCollector = startTelemetry(renderer, "2.5.122", options?.disableTelemetry || false, false);
152
+ if (state.telemetryCollector) state.telemetryCollector.start();
153
+ state.telemetryStartTimeout = null;
154
+ } else state.telemetryStartTimeout = setTimeout(checkRendering, 500);
155
+ };
156
+ state.telemetryStartTimeout = setTimeout(checkRendering, 500);
157
+ }
158
+ return state;
159
+ }
160
+ function teardownState(state) {
161
+ if (state.telemetryCollector) {
162
+ try {
163
+ state.telemetryCollector.stop();
164
+ } catch {}
165
+ state.telemetryCollector = null;
166
+ }
167
+ if (state.telemetryStartTimeout !== null) {
168
+ clearTimeout(state.telemetryStartTimeout);
169
+ state.telemetryStartTimeout = null;
170
+ }
171
+ try {
172
+ state.renderer.cleanup();
173
+ } catch {}
104
174
  }
175
+ current = await build();
105
176
  function update(componentId, props) {
177
+ if (!current) return;
178
+ const { renderer, nodeEntryMap } = current;
106
179
  const entry = nodeEntryMap.get(componentId);
107
180
  if (!entry) {
108
181
  console.warn(`[createShader] Component ID not found: ${componentId}`);
109
182
  return;
110
183
  }
111
- for (const [key, value] of Object.entries(props)) if (METADATA_PROPS.has(key)) if (key === "maskSource") renderer.updateNodeMetadata(entry.nodeId, { mask: value ? {
112
- source: value,
113
- type: props.maskType || entry.component.props?.maskType || "alpha"
114
- } : void 0 });
115
- else if (key === "maskType") continue;
116
- else if (key === "transform") renderer.updateNodeMetadata(entry.nodeId, { transform: value });
117
- else renderer.updateNodeMetadata(entry.nodeId, { [key]: value });
184
+ if (!entry.component.props) entry.component.props = {};
185
+ const live = entry.component.props;
186
+ for (const [key, value] of Object.entries(props)) if (METADATA_PROPS.has(key)) if (key === "maskSource") {
187
+ renderer.updateNodeMetadata(entry.nodeId, { mask: value ? {
188
+ source: value,
189
+ type: props.maskType || live.maskType || "alpha"
190
+ } : void 0 });
191
+ live.maskSource = value;
192
+ if ("maskType" in props) live.maskType = props.maskType;
193
+ } else if (key === "maskType") continue;
194
+ else if (key === "transform") {
195
+ renderer.updateNodeMetadata(entry.nodeId, { transform: value });
196
+ live.transform = value;
197
+ } else {
198
+ renderer.updateNodeMetadata(entry.nodeId, { [key]: value });
199
+ live[key] = value;
200
+ }
118
201
  else if (isPropDriver(value)) if (!Object.prototype.hasOwnProperty.call(entry.componentDef.props, key)) console.warn(`[createShader] Ignoring PropDriver for unknown prop "${key}" on ${entry.component.type}`);
119
202
  else {
120
203
  entry.currentMaps[key] = value;
121
204
  renderer.updateNodeMetadata(entry.nodeId, { maps: { ...entry.currentMaps } });
205
+ live[key] = value;
122
206
  }
123
207
  else {
124
208
  if (key in entry.currentMaps) {
125
209
  delete entry.currentMaps[key];
126
210
  renderer.updateNodeMetadata(entry.nodeId, { maps: Object.keys(entry.currentMaps).length > 0 ? { ...entry.currentMaps } : void 0 });
127
211
  }
128
- if (Object.prototype.hasOwnProperty.call(entry.componentDef.props, key)) renderer.updateUniformValue(entry.nodeId, key, value);
212
+ if (Object.prototype.hasOwnProperty.call(entry.componentDef.props, key)) {
213
+ renderer.updateUniformValue(entry.nodeId, key, value);
214
+ live[key] = value;
215
+ }
129
216
  }
130
217
  }
131
218
  function resize(width, height) {
@@ -135,25 +222,21 @@ async function createShader(canvas, preset, options) {
135
222
  if (w > 0 && h > 0) {
136
223
  canvas.style.width = `${w}px`;
137
224
  canvas.style.height = `${h}px`;
138
- renderer.resize(w, h);
225
+ if (current) current.renderer.resize(w, h);
139
226
  }
140
227
  }
141
228
  function destroy() {
142
- if (telemetryCollector) {
143
- telemetryCollector.stop();
144
- telemetryCollector = null;
145
- }
146
- if (telemetryStartTimeout !== null) {
147
- clearTimeout(telemetryStartTimeout);
148
- telemetryStartTimeout = null;
229
+ destroyed = true;
230
+ if (current) {
231
+ teardownState(current);
232
+ current = null;
149
233
  }
150
- renderer.cleanup();
151
234
  }
152
235
  function pause() {
153
- renderer.stopAnimation();
236
+ if (current) current.renderer.stopAnimation();
154
237
  }
155
238
  function resume() {
156
- renderer.startAnimation();
239
+ if (current) current.renderer.startAnimation();
157
240
  }
158
241
  return {
159
242
  update,
@@ -5,6 +5,20 @@ export interface ShaderOptions {
5
5
  enablePerformanceTracking?: boolean;
6
6
  isPreview?: boolean;
7
7
  onReady?: () => void;
8
+ /**
9
+ * Fires when the underlying GPU device/context is lost — e.g. Chrome
10
+ * evicting a backgrounded tab's WebGPU device, an OS-level GPU reset,
11
+ * driver crash, or `webglcontextlost` on the WebGL fallback path. By the
12
+ * time this callback runs the instance has already started rebuilding
13
+ * itself transparently against the same canvas and preset; the existing
14
+ * `update / pause / resume / resize / destroy` references continue to work
15
+ * once the rebuild completes. The callback is informational — surface a
16
+ * toast, write a log, no action required.
17
+ *
18
+ * @param reason Best-effort string from the underlying API
19
+ * (e.g. `'destroyed'`, `'webglcontextlost'`, GPU error message).
20
+ */
21
+ onError?: (reason: string) => void;
8
22
  /** When false, disables automatic ResizeObserver and IntersectionObserver.
9
23
  * Use resize() for manual sizing and pause()/resume() for animation control.
10
24
  * Defaults to true.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEjE,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;IACjC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;kBAKc;IACd,GAAG,CAAC,EAAE;QACJ,MAAM,EAAE,SAAS,CAAA;QACjB,OAAO,EAAE,UAAU,CAAA;KACpB,CAAA;CACF;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,aAAa,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,iGAAiG;IACjG,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC/D;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;IAC7D;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,mFAAmF;IACnF,KAAK,IAAI,IAAI,CAAA;IACb,kDAAkD;IAClD,MAAM,IAAI,IAAI,CAAA;IACd,OAAO,IAAI,IAAI,CAAA;CAChB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAEjE,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,WAAW,GAAG,MAAM,CAAA;IACjC,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAA;IACnC,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAClC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB;;;;;kBAKc;IACd,GAAG,CAAC,EAAE;QACJ,MAAM,EAAE,SAAS,CAAA;QACjB,OAAO,EAAE,UAAU,CAAA;KACpB,CAAA;CACF;AAED,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,aAAa,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACvC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,iGAAiG;IACjG,gBAAgB,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;CAC/D;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;IAC7D;;;;OAIG;IACH,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7C,mFAAmF;IACnF,KAAK,IAAI,IAAI,CAAA;IACb,kDAAkD;IAClD,MAAM,IAAI,IAAI,CAAA;IACd,OAAO,IAAI,IAAI,CAAA;CAChB"}
@@ -10,10 +10,19 @@ export interface PartnerPresetDefinition {
10
10
  colorSpace?: string;
11
11
  devicePreview?: string;
12
12
  }
13
+ /**
14
+ * Top-level groupings the dotcom catalogues shaders under. Pass to
15
+ * `listPresets({ categories })` to narrow the response. Omit to receive every
16
+ * category.
17
+ */
18
+ export type CollectionCategory = 'background' | 'logo' | 'image-effects';
13
19
  export interface PartnerCollection {
14
20
  id: string;
15
21
  name: string;
16
22
  slug: string;
23
+ /** Top-level grouping. Useful when partners want to render section
24
+ * headings or filter the list further client-side. */
25
+ category: CollectionCategory;
17
26
  }
18
27
  export type PartnerPresetLabel = 'gradient' | 'geometric' | 'organic' | 'glowing' | 'textured' | 'retro' | '3d' | 'minimal' | 'vibrant' | 'dark' | 'calm' | 'dramatic';
19
28
  export interface PartnerKeyPropTarget {
@@ -56,6 +65,13 @@ export interface PartnerClientOptions {
56
65
  export interface ListPresetsOptions {
57
66
  page?: number;
58
67
  limit?: number;
68
+ /**
69
+ * Restrict the response to one or more categories. Omit to receive every
70
+ * category (the default — what you want for a general-purpose integration).
71
+ * Supply a subset (e.g. `['logo']`) when the integration only renders one
72
+ * kind of shader, so you don't pull rows you'll never show.
73
+ */
74
+ categories?: CollectionCategory[];
59
75
  }
60
76
  export declare class PartnerClient {
61
77
  private readonly apiKey;
@@ -65,5 +81,29 @@ export declare class PartnerClient {
65
81
  private getCached;
66
82
  private setCached;
67
83
  listPresets(options?: ListPresetsOptions): Promise<PartnerListPresetsResponse>;
84
+ /**
85
+ * Generate an SDF (signed distance field) `.bin` file from raw SVG content.
86
+ * Resolves to the file's bytes as a `Uint8Array` — the caller can write it
87
+ * to disk, upload it to their own CDN, or feed it straight into a shader
88
+ * component that consumes SDF buffers.
89
+ *
90
+ * Backed by the public `/api/plugin/sdf/generate` endpoint, which is shared
91
+ * with the Framer plugin. The endpoint is anonymous (no API key required);
92
+ * Vercel-side rate limits apply. Maximum input size: 5 MB of SVG text.
93
+ *
94
+ * Not cached — the same SVG fed in twice will round-trip twice. Memoize
95
+ * upstream if you need to.
96
+ *
97
+ * @example
98
+ * ```ts
99
+ * const fs = await import('node:fs/promises')
100
+ * const svg = await fs.readFile('./logo.svg', 'utf8')
101
+ * const sdf = await client.generateSdf(svg)
102
+ * await fs.writeFile('./logo.sdf.bin', sdf)
103
+ * ```
104
+ */
105
+ generateSdf(svg: string, options?: {
106
+ timeoutMs?: number;
107
+ }): Promise<Uint8Array>;
68
108
  }
69
109
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,QAAQ,CAAC,EAAE,sBAAsB,EAAE,CAAA;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,sBAAsB,EAAE,CAAA;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,CAAA;AAEtK,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,oBAAoB,EAAE,CAAA;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAA;IACV,UAAU,EAAE,iBAAiB,GAAG,IAAI,CAAA;IACpC,UAAU,EAAE,uBAAuB,CAAA;IACnC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAA;IACjC,cAAc,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAC/B,eAAe,EAAE,MAAM,EAAE,GAAG,IAAI,CAAA;IAChC,MAAM,EAAE,kBAAkB,EAAE,GAAG,IAAI,CAAA;IACnC,SAAS,EAAE,cAAc,EAAE,GAAG,IAAI,CAAA;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB,UAAU,EAAE,iBAAiB,CAAA;CAC9B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAUD,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAyC;gBAEnD,OAAO,EAAE,oBAAoB;IAMzC,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,SAAS;IAIX,WAAW,CAAC,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,0BAA0B,CAAC;CA6BzF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -22,12 +22,16 @@ class PartnerClient {
22
22
  async listPresets(options = {}) {
23
23
  const page = Math.max(1, options.page ?? 1);
24
24
  const limit = Math.min(100, Math.max(1, options.limit ?? 20));
25
- const cacheKey = `presets:p${page}:l${limit}`;
25
+ const categories = options.categories && options.categories.length > 0 ? [...new Set(options.categories)].sort() : null;
26
+ const cacheKey = `presets:p${page}:l${limit}:c${(categories == null ? void 0 : categories.join(",")) ?? "*"}`;
26
27
  const cached = this.getCached(cacheKey);
27
28
  if (cached) return cached;
28
29
  const url = new URL(`${this.baseUrl}/api/partner/v1/presets`);
29
30
  url.searchParams.set("page", String(page));
30
31
  url.searchParams.set("limit", String(limit));
32
+ if (categories) {
33
+ url.searchParams.set("categories", categories.join(","));
34
+ }
31
35
  const response = await fetch(url.toString(), {
32
36
  headers: { Authorization: `Bearer ${this.apiKey}` }
33
37
  });
@@ -44,6 +48,62 @@ class PartnerClient {
44
48
  this.setCached(cacheKey, data);
45
49
  return data;
46
50
  }
51
+ /**
52
+ * Generate an SDF (signed distance field) `.bin` file from raw SVG content.
53
+ * Resolves to the file's bytes as a `Uint8Array` — the caller can write it
54
+ * to disk, upload it to their own CDN, or feed it straight into a shader
55
+ * component that consumes SDF buffers.
56
+ *
57
+ * Backed by the public `/api/plugin/sdf/generate` endpoint, which is shared
58
+ * with the Framer plugin. The endpoint is anonymous (no API key required);
59
+ * Vercel-side rate limits apply. Maximum input size: 5 MB of SVG text.
60
+ *
61
+ * Not cached — the same SVG fed in twice will round-trip twice. Memoize
62
+ * upstream if you need to.
63
+ *
64
+ * @example
65
+ * ```ts
66
+ * const fs = await import('node:fs/promises')
67
+ * const svg = await fs.readFile('./logo.svg', 'utf8')
68
+ * const sdf = await client.generateSdf(svg)
69
+ * await fs.writeFile('./logo.sdf.bin', sdf)
70
+ * ```
71
+ */
72
+ async generateSdf(svg, options = {}) {
73
+ if (typeof svg !== "string" || svg.length === 0) {
74
+ throw new Error("generateSdf requires a non-empty SVG string");
75
+ }
76
+ const timeoutMs = options.timeoutMs ?? 3e4;
77
+ const controller = new AbortController();
78
+ const timeoutHandle = setTimeout(() => controller.abort(), timeoutMs);
79
+ try {
80
+ const response = await fetch(`${this.baseUrl}/api/plugin/sdf/generate`, {
81
+ method: "POST",
82
+ headers: { "Content-Type": "application/json" },
83
+ body: JSON.stringify({ svg }),
84
+ signal: controller.signal
85
+ });
86
+ if (!response.ok) {
87
+ let message = response.statusText;
88
+ try {
89
+ const body = await response.json();
90
+ if (body.message) message = body.message;
91
+ else if (body.error) message = body.error;
92
+ } catch {
93
+ }
94
+ throw new Error(`SDF generation failed ${response.status}: ${message}`);
95
+ }
96
+ const buffer = await response.arrayBuffer();
97
+ return new Uint8Array(buffer);
98
+ } catch (err) {
99
+ if (err instanceof Error && err.name === "AbortError") {
100
+ throw new Error(`SDF generation timed out after ${timeoutMs}ms`);
101
+ }
102
+ throw err;
103
+ } finally {
104
+ clearTimeout(timeoutHandle);
105
+ }
106
+ }
47
107
  }
48
108
  export {
49
109
  PartnerClient