@sarmal/core 0.28.0 → 0.29.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sarmal/core",
3
- "version": "0.28.0",
3
+ "version": "0.29.0",
4
4
  "description": "Curve path based loading indicators and their renderer",
5
5
  "keywords": [
6
6
  "animation",
@@ -9,7 +9,8 @@
9
9
  "loading",
10
10
  "parametric",
11
11
  "spinner",
12
- "svg"
12
+ "svg",
13
+ "tanstack-intent"
13
14
  ],
14
15
  "homepage": "https://sarmal.art",
15
16
  "bugs": {
@@ -31,7 +32,8 @@
31
32
  },
32
33
  "files": [
33
34
  "dist",
34
- "LICENSE"
35
+ "LICENSE",
36
+ "skills"
35
37
  ],
36
38
  "type": "module",
37
39
  "sideEffects": [
@@ -68,6 +70,9 @@
68
70
  "types": "./dist/terminal.d.ts"
69
71
  }
70
72
  },
73
+ "publishConfig": {
74
+ "access": "public"
75
+ },
71
76
  "scripts": {
72
77
  "build": "tsup",
73
78
  "dev": "tsup --watch",
@@ -0,0 +1,151 @@
1
+ ---
2
+ name: core
3
+ description: Parametric curve loading indicators for the web. Use when adding animated
4
+ spinners or loading indicators with @sarmal/core — covers createSarmal (canvas),
5
+ createSarmalSVG, built-in curves, lifecycle, and animation controls.
6
+ license: MIT
7
+ ---
8
+
9
+ # @sarmal/core
10
+
11
+ sarmal renders parametric math curves as animated loading/thinking indicators. It is not a CSS spinner — it is a canvas or SVG renderer that animates a moving "head" dot leaving a fading trail along a curve path.
12
+
13
+ ## Type definitions (read these first)
14
+
15
+ The package ships TypeScript definitions that are the authoritative, always-current API reference. Read them before writing any code:
16
+
17
+ - `node_modules/@sarmal/core/dist/index.d.ts` — `SarmalInstance`, `SarmalOptions`, `createSarmal`, `createSarmalSVG`, `RuntimeRenderOptions`, `TrailStyle`, `TrailColor`, and all other types
18
+ - `node_modules/@sarmal/core/dist/curves/index.d.ts` — `CurveName` union type listing every available built-in curve name; individual curve exports
19
+
20
+ Do not rely on training data for option names, defaults, or curve names — read the `.d.ts` files.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install @sarmal/core
26
+ ```
27
+
28
+ ## Entry points
29
+
30
+ ```ts
31
+ import { createSarmal, createSarmalSVG, curves } from "@sarmal/core";
32
+ ```
33
+
34
+ **`createSarmal(canvas, curveDef, options?): SarmalInstance`** — canvas renderer
35
+ **`createSarmalSVG(svg, curveDef, options?): SarmalInstance`** — SVG renderer
36
+
37
+ Both accept the same options and return the same `SarmalInstance` interface.
38
+
39
+ ## Using built-in curves
40
+
41
+ ```ts
42
+ // Named import (tree-shakeable):
43
+ import { lissajous32 } from "@sarmal/core";
44
+ const sarmal = createSarmal(canvas, lissajous32);
45
+
46
+ // Or look up by name string from the curves namespace:
47
+ import { curves } from "@sarmal/core";
48
+ const sarmal = createSarmal(canvas, curves["rose5"]);
49
+ ```
50
+
51
+ For all available curve names, read the `CurveName` type in `dist/curves/index.d.ts`.
52
+
53
+ ## Coordinate space — most important gotcha
54
+
55
+ The two renderers use **different coordinate spaces** for all size values:
56
+
57
+ | Renderer | Space | `headRadius` default |
58
+ | ----------------------- | ------------------- | -------------------- |
59
+ | `createSarmal` (canvas) | CSS pixels | `4` |
60
+ | `createSarmalSVG` (SVG) | 0–100 viewBox units | `0.5` |
61
+
62
+ When configuring `headRadius` or any size option for the SVG renderer, use viewBox units (e.g. `1`–`3`), not pixel values. Passing a canvas-appropriate value like `4` to the SVG renderer produces a massive dot.
63
+
64
+ The same applies to `setRenderOptions` calls on SVG instances.
65
+
66
+ ## Lifecycle
67
+
68
+ ```ts
69
+ const sarmal = createSarmal(canvas, curveDef, { autoStart: false });
70
+
71
+ sarmal.play(); // start the animation loop
72
+ sarmal.pause(); // pause — preserves animation state
73
+ sarmal.destroy(); // REQUIRED: stops the loop and frees resources
74
+ ```
75
+
76
+ **Always call `destroy()`** when removing the element or unmounting a component. Omitting it leaks a `requestAnimationFrame` loop.
77
+
78
+ ## Animation controls
79
+
80
+ ```ts
81
+ // Move to a phase position AND rebuild the trail as if the animation arrived naturally
82
+ sarmal.seek(Math.PI);
83
+
84
+ // Instantly teleport the head; trail is left untouched
85
+ sarmal.jump(Math.PI);
86
+ sarmal.jump(Math.PI, { clearTrail: true }); // or clear it
87
+
88
+ // Speed (0 = freeze, negative = reverse, no upper bound)
89
+ sarmal.setSpeed(2);
90
+ sarmal.resetSpeed(); // revert to curve's inherent default
91
+ await sarmal.setSpeedOver(0, 400); // smooth transition over 400ms
92
+
93
+ // Smooth curve transition (default 300ms)
94
+ await sarmal.morphTo(rose5);
95
+ await sarmal.morphTo(rose5, { duration: 600 });
96
+ ```
97
+
98
+ **`seek` vs `jump`:** `seek` reconstructs the trail so it looks like the head arrived naturally — use for initialisation. `jump` moves the head instantly without touching the trail — use during morphs or mid-flight repositioning.
99
+
100
+ ## Runtime style changes
101
+
102
+ A subset of options can be changed on a live instance via `setRenderOptions`. For the exact list, read `RuntimeRenderOptions` in `dist/index.d.ts`. Validation is strict — if any field fails, the entire call is rejected.
103
+
104
+ ```ts
105
+ sarmal.setRenderOptions({
106
+ trailColor: ["#ff0000", "#0000ff"],
107
+ trailStyle: "gradient-animated",
108
+ skeletonColor: "transparent", // hides the skeleton
109
+ headColor: null, // null = derive from trail automatically
110
+ });
111
+ ```
112
+
113
+ ## Auto-init (no JS required)
114
+
115
+ ```ts
116
+ import "@sarmal/core/auto";
117
+ ```
118
+
119
+ ```html
120
+ <canvas data-sarmal="lissajous32" width="200" height="200"></canvas>
121
+ <svg data-sarmal="rose5" width="200" height="200"></svg>
122
+ ```
123
+
124
+ Data attributes mirror the option names in kebab-case: `data-trail-color`, `data-trail-length`, `data-trail-style`, `data-skeleton-color`, `data-head-color`, `data-head-radius`.
125
+
126
+ ## CDN usage
127
+
128
+ ES module:
129
+
130
+ ```html
131
+ <script type="module">
132
+ import { createSarmal, lissajous32 } from "https://cdn.jsdelivr.net/npm/@sarmal/core/+esm";
133
+ const sarmal = createSarmal(document.querySelector("canvas"), lissajous32);
134
+ </script>
135
+ ```
136
+
137
+ Auto-init script (no JS needed):
138
+
139
+ ```html
140
+ <script src="https://cdn.jsdelivr.net/npm/@sarmal/core/dist/auto-init.js"></script>
141
+ <canvas data-sarmal="rose5" width="200" height="200"></canvas>
142
+ ```
143
+
144
+ ## Common mistakes
145
+
146
+ - **`trailColor` with named colors or `rgb()`** — only 6-digit hex strings are supported; `'red'` and `'#f00'` are not valid
147
+ - **SVG `headRadius` with pixel values** — SVG space is 0–100 viewBox units; a canvas value of `4` renders as a large dot in SVG
148
+ - **Forgetting `destroy()`** — always clean up in React `useEffect` return, Vue `onUnmounted`, etc.
149
+ - **Changing `trailLength` after construction** — not possible; `trailLength` is fixed at creation; create a new instance
150
+ - **Gradient colors without a gradient `trailStyle`** — `string[]` for `trailColor` has no visual effect unless `trailStyle` is `'gradient-static'` or `'gradient-animated'`
151
+ - **Reading trail length from `trail.length`** — when using the engine directly, use `engine.trailCount`; the buffer is pre-allocated and always full-length