@sarmal/core 0.37.4 → 0.38.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/dist/auto-init.cjs +111 -14
- package/dist/auto-init.cjs.map +1 -1
- package/dist/auto-init.js +111 -14
- package/dist/auto-init.js.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/curves/artemis2.d.cts +1 -1
- package/dist/curves/artemis2.d.ts +1 -1
- package/dist/curves/astroid.d.cts +1 -1
- package/dist/curves/astroid.d.ts +1 -1
- package/dist/curves/deltoid.d.cts +1 -1
- package/dist/curves/deltoid.d.ts +1 -1
- package/dist/curves/epicycloid3.d.cts +1 -1
- package/dist/curves/epicycloid3.d.ts +1 -1
- package/dist/curves/epitrochoid7.d.cts +1 -1
- package/dist/curves/epitrochoid7.d.ts +1 -1
- package/dist/curves/index.d.cts +1 -1
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/lame.d.cts +1 -1
- package/dist/curves/lame.d.ts +1 -1
- package/dist/curves/lissajous32.d.cts +1 -1
- package/dist/curves/lissajous32.d.ts +1 -1
- package/dist/curves/lissajous43.d.cts +1 -1
- package/dist/curves/lissajous43.d.ts +1 -1
- package/dist/curves/rose3.d.cts +1 -1
- package/dist/curves/rose3.d.ts +1 -1
- package/dist/curves/rose5.d.cts +1 -1
- package/dist/curves/rose5.d.ts +1 -1
- package/dist/curves/rose52.d.cts +1 -1
- package/dist/curves/rose52.d.ts +1 -1
- package/dist/curves/star.d.cts +1 -1
- package/dist/curves/star.d.ts +1 -1
- package/dist/curves/star4.d.cts +1 -1
- package/dist/curves/star4.d.ts +1 -1
- package/dist/curves/star7.d.cts +1 -1
- package/dist/curves/star7.d.ts +1 -1
- package/dist/index.cjs +111 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +111 -14
- package/dist/index.js.map +1 -1
- package/dist/{renderer-shared-DElz98PT.d.ts → renderer-shared-2tEwOWJm.d.ts} +1 -1
- package/dist/{renderer-shared-9Xf6sIlx.d.cts → renderer-shared-Bh33A5Av.d.cts} +1 -1
- package/dist/terminal.cjs.map +1 -1
- package/dist/terminal.d.cts +2 -2
- package/dist/terminal.d.ts +2 -2
- package/dist/terminal.js.map +1 -1
- package/dist/{types-D_ERoVvi.d.cts → types-CmPFR9U3.d.cts} +5 -1
- package/dist/{types-D_ERoVvi.d.ts → types-CmPFR9U3.d.ts} +5 -1
- package/package.json +1 -1
package/dist/auto-init.cjs
CHANGED
|
@@ -364,15 +364,42 @@ function computeBoundaries(pts, logicalWidth, logicalHeight, minPaddingPx = FIT_
|
|
|
364
364
|
offsetY: (logicalHeight - h * scale) / 2 - minY * scale
|
|
365
365
|
};
|
|
366
366
|
}
|
|
367
|
-
|
|
367
|
+
var DESTROYED_ERROR = "[sarmal] Instance has been destroyed and cannot be used again. Call pause() instead of destroy() for temporary suspension.";
|
|
368
|
+
function enginePassthroughs(engine, isDestroyed) {
|
|
369
|
+
function guard() {
|
|
370
|
+
if (isDestroyed()) {
|
|
371
|
+
throw new Error(DESTROYED_ERROR);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
368
374
|
return {
|
|
369
|
-
jump
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
375
|
+
jump(phase, options) {
|
|
376
|
+
guard();
|
|
377
|
+
engine.jump(phase, options);
|
|
378
|
+
},
|
|
379
|
+
seek(phase, options) {
|
|
380
|
+
guard();
|
|
381
|
+
engine.seek(phase, options);
|
|
382
|
+
},
|
|
383
|
+
setSpeed(speed) {
|
|
384
|
+
guard();
|
|
385
|
+
engine.setSpeed(speed);
|
|
386
|
+
},
|
|
387
|
+
getSpeed() {
|
|
388
|
+
guard();
|
|
389
|
+
return engine.getSpeed();
|
|
390
|
+
},
|
|
391
|
+
resetSpeed() {
|
|
392
|
+
guard();
|
|
393
|
+
engine.resetSpeed();
|
|
394
|
+
},
|
|
395
|
+
setSpeedOver(speed, duration) {
|
|
396
|
+
guard();
|
|
397
|
+
return engine.setSpeedOver(speed, duration);
|
|
398
|
+
},
|
|
399
|
+
getSarmalSkeleton() {
|
|
400
|
+
guard();
|
|
401
|
+
return engine.getSarmalSkeleton();
|
|
402
|
+
}
|
|
376
403
|
};
|
|
377
404
|
}
|
|
378
405
|
function hexToRgb(hex) {
|
|
@@ -731,6 +758,7 @@ function createRenderer(options) {
|
|
|
731
758
|
let animationId = null;
|
|
732
759
|
let lastTime = 0;
|
|
733
760
|
let pausedByVisibility = false;
|
|
761
|
+
let destroyed = false;
|
|
734
762
|
let morphResolve = null;
|
|
735
763
|
let morphReject = null;
|
|
736
764
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
@@ -902,6 +930,9 @@ function createRenderer(options) {
|
|
|
902
930
|
const shouldAutoStart = options.autoStart !== false;
|
|
903
931
|
const instance = {
|
|
904
932
|
play() {
|
|
933
|
+
if (destroyed) {
|
|
934
|
+
throw new Error(DESTROYED_ERROR);
|
|
935
|
+
}
|
|
905
936
|
if (animationId !== null) {
|
|
906
937
|
return;
|
|
907
938
|
}
|
|
@@ -909,6 +940,9 @@ function createRenderer(options) {
|
|
|
909
940
|
loop();
|
|
910
941
|
},
|
|
911
942
|
pause() {
|
|
943
|
+
if (destroyed) {
|
|
944
|
+
throw new Error(DESTROYED_ERROR);
|
|
945
|
+
}
|
|
912
946
|
if (animationId === null) {
|
|
913
947
|
return;
|
|
914
948
|
}
|
|
@@ -917,24 +951,36 @@ function createRenderer(options) {
|
|
|
917
951
|
engine.cancelSpeedTransition();
|
|
918
952
|
},
|
|
919
953
|
reset() {
|
|
954
|
+
if (destroyed) {
|
|
955
|
+
throw new Error(DESTROYED_ERROR);
|
|
956
|
+
}
|
|
920
957
|
engine.reset();
|
|
921
958
|
trail = [];
|
|
922
959
|
head = null;
|
|
923
960
|
},
|
|
924
961
|
destroy() {
|
|
962
|
+
if (destroyed) {
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
destroyed = true;
|
|
925
966
|
if (animationId !== null) {
|
|
926
967
|
cancelAnimationFrame(animationId);
|
|
927
968
|
animationId = null;
|
|
928
969
|
}
|
|
929
970
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
971
|
+
engine.cancelSpeedTransition();
|
|
930
972
|
if (morphReject !== null) {
|
|
931
|
-
morphReject(new Error("Instance destroyed during morph"));
|
|
973
|
+
morphReject(new Error("[sarmal] Instance destroyed during morph"));
|
|
932
974
|
morphResolve = null;
|
|
933
975
|
morphReject = null;
|
|
934
976
|
}
|
|
977
|
+
ctx.clearRect(0, 0, logicalWidth, logicalHeight);
|
|
935
978
|
},
|
|
936
|
-
...enginePassthroughs(engine),
|
|
979
|
+
...enginePassthroughs(engine, () => destroyed),
|
|
937
980
|
morphTo(target, options2) {
|
|
981
|
+
if (destroyed) {
|
|
982
|
+
throw new Error(DESTROYED_ERROR);
|
|
983
|
+
}
|
|
938
984
|
if (morphResolve !== null) {
|
|
939
985
|
engine.completeMorph();
|
|
940
986
|
morphResolve();
|
|
@@ -951,6 +997,9 @@ function createRenderer(options) {
|
|
|
951
997
|
});
|
|
952
998
|
},
|
|
953
999
|
setRenderOptions(partial) {
|
|
1000
|
+
if (destroyed) {
|
|
1001
|
+
throw new Error(DESTROYED_ERROR);
|
|
1002
|
+
}
|
|
954
1003
|
validateRenderOptions(partial);
|
|
955
1004
|
if (partial.trailColor !== void 0) {
|
|
956
1005
|
trailColor = partial.trailColor;
|
|
@@ -1205,6 +1254,7 @@ function createSVGRenderer(options) {
|
|
|
1205
1254
|
let animationId = null;
|
|
1206
1255
|
let lastTime = 0;
|
|
1207
1256
|
let pausedByVisibility = false;
|
|
1257
|
+
let destroyed = false;
|
|
1208
1258
|
const prefersReducedMotion = typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
1209
1259
|
let morphResolve = null;
|
|
1210
1260
|
let morphReject = null;
|
|
@@ -1273,6 +1323,9 @@ function createSVGRenderer(options) {
|
|
|
1273
1323
|
const shouldAutoStart = options.autoStart !== false;
|
|
1274
1324
|
const instance = {
|
|
1275
1325
|
play() {
|
|
1326
|
+
if (destroyed) {
|
|
1327
|
+
throw new Error(DESTROYED_ERROR);
|
|
1328
|
+
}
|
|
1276
1329
|
if (animationId !== null) {
|
|
1277
1330
|
return;
|
|
1278
1331
|
}
|
|
@@ -1280,6 +1333,9 @@ function createSVGRenderer(options) {
|
|
|
1280
1333
|
loop();
|
|
1281
1334
|
},
|
|
1282
1335
|
pause() {
|
|
1336
|
+
if (destroyed) {
|
|
1337
|
+
throw new Error(DESTROYED_ERROR);
|
|
1338
|
+
}
|
|
1283
1339
|
if (animationId === null) {
|
|
1284
1340
|
return;
|
|
1285
1341
|
}
|
|
@@ -1288,23 +1344,34 @@ function createSVGRenderer(options) {
|
|
|
1288
1344
|
engine.cancelSpeedTransition();
|
|
1289
1345
|
},
|
|
1290
1346
|
reset() {
|
|
1347
|
+
if (destroyed) {
|
|
1348
|
+
throw new Error(DESTROYED_ERROR);
|
|
1349
|
+
}
|
|
1291
1350
|
engine.reset();
|
|
1292
1351
|
},
|
|
1293
1352
|
destroy() {
|
|
1353
|
+
if (destroyed) {
|
|
1354
|
+
return;
|
|
1355
|
+
}
|
|
1356
|
+
destroyed = true;
|
|
1294
1357
|
if (animationId !== null) {
|
|
1295
1358
|
cancelAnimationFrame(animationId);
|
|
1296
1359
|
animationId = null;
|
|
1297
1360
|
}
|
|
1298
1361
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1362
|
+
engine.cancelSpeedTransition();
|
|
1299
1363
|
if (morphReject !== null) {
|
|
1300
|
-
morphReject(new Error("Instance destroyed during morph"));
|
|
1364
|
+
morphReject(new Error("[sarmal] Instance destroyed during morph"));
|
|
1301
1365
|
morphResolve = null;
|
|
1302
1366
|
morphReject = null;
|
|
1303
1367
|
}
|
|
1304
1368
|
group.remove();
|
|
1305
1369
|
},
|
|
1306
|
-
...enginePassthroughs(engine),
|
|
1370
|
+
...enginePassthroughs(engine, () => destroyed),
|
|
1307
1371
|
morphTo(target, options2) {
|
|
1372
|
+
if (destroyed) {
|
|
1373
|
+
throw new Error(DESTROYED_ERROR);
|
|
1374
|
+
}
|
|
1308
1375
|
if (morphResolve !== null) {
|
|
1309
1376
|
engine.completeMorph();
|
|
1310
1377
|
morphResolve();
|
|
@@ -1330,6 +1397,9 @@ function createSVGRenderer(options) {
|
|
|
1330
1397
|
});
|
|
1331
1398
|
},
|
|
1332
1399
|
setRenderOptions(partial) {
|
|
1400
|
+
if (destroyed) {
|
|
1401
|
+
throw new Error(DESTROYED_ERROR);
|
|
1402
|
+
}
|
|
1333
1403
|
validateRenderOptions(partial);
|
|
1334
1404
|
const prevTrailStyle = trailStyle;
|
|
1335
1405
|
if (partial.trailColor !== void 0) {
|
|
@@ -1459,6 +1529,7 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1459
1529
|
let animationId = null;
|
|
1460
1530
|
let lastTime = 0;
|
|
1461
1531
|
let pausedByVisibility = false;
|
|
1532
|
+
let destroyed = false;
|
|
1462
1533
|
let morphResolve = null;
|
|
1463
1534
|
let morphReject = null;
|
|
1464
1535
|
let morphDurationMs = DEFAULT_MORPH_DURATION_MS;
|
|
@@ -1712,6 +1783,9 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1712
1783
|
const instance = {
|
|
1713
1784
|
/** Starts the animation loop. Does nothing if already running. */
|
|
1714
1785
|
play() {
|
|
1786
|
+
if (destroyed) {
|
|
1787
|
+
throw new Error(DESTROYED_ERROR);
|
|
1788
|
+
}
|
|
1715
1789
|
if (animationId !== null) {
|
|
1716
1790
|
return;
|
|
1717
1791
|
}
|
|
@@ -1720,6 +1794,9 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1720
1794
|
},
|
|
1721
1795
|
/** Pauses the animation loop. Preserves current trail state. */
|
|
1722
1796
|
pause() {
|
|
1797
|
+
if (destroyed) {
|
|
1798
|
+
throw new Error(DESTROYED_ERROR);
|
|
1799
|
+
}
|
|
1723
1800
|
if (animationId === null) {
|
|
1724
1801
|
return;
|
|
1725
1802
|
}
|
|
@@ -1729,29 +1806,46 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1729
1806
|
},
|
|
1730
1807
|
/** Resets the animation to the start of the curve and clears the grid. */
|
|
1731
1808
|
reset() {
|
|
1809
|
+
if (destroyed) {
|
|
1810
|
+
throw new Error(DESTROYED_ERROR);
|
|
1811
|
+
}
|
|
1732
1812
|
engine.reset();
|
|
1733
1813
|
grid.fill(0);
|
|
1734
1814
|
},
|
|
1735
|
-
/**
|
|
1815
|
+
/**
|
|
1816
|
+
* Permanently stops the animation and clears the visual output.
|
|
1817
|
+
* Calling any method on a destroyed instance throws an error.
|
|
1818
|
+
* `destroy()` is idempotent — calling it multiple times is safe.
|
|
1819
|
+
*/
|
|
1736
1820
|
destroy() {
|
|
1821
|
+
if (destroyed) {
|
|
1822
|
+
return;
|
|
1823
|
+
}
|
|
1824
|
+
destroyed = true;
|
|
1737
1825
|
if (animationId !== null) {
|
|
1738
1826
|
cancelAnimationFrame(animationId);
|
|
1739
1827
|
animationId = null;
|
|
1740
1828
|
}
|
|
1741
1829
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
1830
|
+
engine.cancelSpeedTransition();
|
|
1742
1831
|
if (morphReject !== null) {
|
|
1743
1832
|
morphReject(new Error("[sarmal] Instance destroyed during morph"));
|
|
1744
1833
|
morphResolve = null;
|
|
1745
1834
|
morphReject = null;
|
|
1746
1835
|
}
|
|
1836
|
+
grid.fill(0);
|
|
1837
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
1747
1838
|
},
|
|
1748
|
-
...enginePassthroughs(engine),
|
|
1839
|
+
...enginePassthroughs(engine, () => destroyed),
|
|
1749
1840
|
/**
|
|
1750
1841
|
* Smoothly transitions from the current curve to `target`.
|
|
1751
1842
|
* If a morph is already in progress, it is snapped to completion before the new one starts.
|
|
1752
1843
|
* @returns A Promise that resolves when the transition finishes.
|
|
1753
1844
|
*/
|
|
1754
1845
|
morphTo(target, opts) {
|
|
1846
|
+
if (destroyed) {
|
|
1847
|
+
throw new Error(DESTROYED_ERROR);
|
|
1848
|
+
}
|
|
1755
1849
|
if (morphResolve !== null) {
|
|
1756
1850
|
completeMorphNow();
|
|
1757
1851
|
}
|
|
@@ -1771,6 +1865,9 @@ function createSarmalDotMatrix(canvas, curveDef, options) {
|
|
|
1771
1865
|
* ! Validation fails the entire call if any field is invalid, leaving options unchanged.
|
|
1772
1866
|
*/
|
|
1773
1867
|
setRenderOptions(partial) {
|
|
1868
|
+
if (destroyed) {
|
|
1869
|
+
throw new Error(DESTROYED_ERROR);
|
|
1870
|
+
}
|
|
1774
1871
|
validateBaseRenderOptions(partial);
|
|
1775
1872
|
let needsRebuildBg = false;
|
|
1776
1873
|
if (partial.trailColor !== void 0) {
|