@fusion.dev/helix-theme 0.0.9 → 0.3.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 +37 -0
- package/dist/index.js +0 -33
- package/dist/types.js +0 -9
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @fusion.dev/helix-theme
|
|
2
|
+
|
|
3
|
+
The theme derivation engine. Computes a complete, contrast-guaranteed token set
|
|
4
|
+
from a small set of intent inputs.
|
|
5
|
+
|
|
6
|
+
```sh
|
|
7
|
+
npm install @fusion.dev/helix-theme
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
import { initTheme } from '@fusion.dev/helix-theme'
|
|
12
|
+
|
|
13
|
+
const engine = await initTheme('/helix/theme.wasm')
|
|
14
|
+
const theme = engine.derive({ brand: '#3b82f6' }, [':root'])
|
|
15
|
+
|
|
16
|
+
document.head.append(Object.assign(document.createElement('style'), {
|
|
17
|
+
textContent: theme.css[':root'],
|
|
18
|
+
}))
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Give it what you mean — a brand color, and whatever else you have an opinion
|
|
22
|
+
about — and it returns every token the system needs with the contrast
|
|
23
|
+
relationships already satisfied, rather than a palette you then have to check.
|
|
24
|
+
|
|
25
|
+
**It has to be awaited and there is no way around that.** WebAssembly
|
|
26
|
+
instantiates asynchronously, so the engine is handed back from `initTheme`
|
|
27
|
+
rather than being importable: you cannot hold one without having waited for it.
|
|
28
|
+
|
|
29
|
+
The derivation is Rust and ships as WASM, so the same arithmetic runs in a
|
|
30
|
+
browser, in a build step and in the CLI, rather than two implementations
|
|
31
|
+
disagreeing by construction.
|
|
32
|
+
|
|
33
|
+
Zero dependencies and zero peers: it computes values and touches no DOM.
|
|
34
|
+
|
|
35
|
+
[Documentation](https://helix.fusion.dev) · [Theme builder](https://helix.fusion.dev/theme)
|
|
36
|
+
|
|
37
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -1,38 +1,5 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The theme engine, reached from JavaScript.
|
|
3
|
-
*
|
|
4
|
-
* **One implementation, two distributions.** The derivation is Rust: it is a
|
|
5
|
-
* search, and `fitToGamut` is a twenty-step bisection while
|
|
6
|
-
* `lightnessForContrast` searches too, so iteration count, bisection order and
|
|
7
|
-
* float arithmetic are implementation choices. Two implementations of that
|
|
8
|
-
* disagree by construction rather than by accident, which is why this package
|
|
9
|
-
* stopped being an engine and became a way to reach one.
|
|
10
|
-
*
|
|
11
|
-
* **It has to be awaited, and there is no way around that.** WebAssembly
|
|
12
|
-
* instantiates asynchronously, so a module-level `deriveTheme` would either
|
|
13
|
-
* block or throw for anybody who called it before the module landed. Handing the
|
|
14
|
-
* engine back from `initTheme` makes the fact unavoidable rather than a runtime
|
|
15
|
-
* error somebody meets in production: you cannot hold a `ThemeEngine` without
|
|
16
|
-
* having waited for one.
|
|
17
|
-
*
|
|
18
|
-
* ```ts
|
|
19
|
-
* const engine = await initTheme('/helix/theme.wasm')
|
|
20
|
-
* const theme = engine.derive({ brand: '#3b82f6' }, [':root'])
|
|
21
|
-
* document.head.append(Object.assign(document.createElement('style'), {
|
|
22
|
-
* textContent: theme.css[':root'],
|
|
23
|
-
* }))
|
|
24
|
-
* ```
|
|
25
|
-
*/
|
|
26
1
|
import initWasm, { derive, hexToOklch as readHex } from '../wasm/fusion_helix_theme.js';
|
|
27
2
|
let loading;
|
|
28
|
-
/**
|
|
29
|
-
* Loads the engine, once.
|
|
30
|
-
*
|
|
31
|
-
* **The promise is cached rather than the result**, so two callers racing at
|
|
32
|
-
* startup get one instantiation and both wait on it. Caching the resolved value
|
|
33
|
-
* instead would let the second call start a second download before the first
|
|
34
|
-
* finished.
|
|
35
|
-
*/
|
|
36
3
|
export function initTheme(source) {
|
|
37
4
|
loading ??= initWasm({ module_or_path: source }).then(() => ({
|
|
38
5
|
derive: (intent, selectors = []) => JSON.parse(derive(JSON.stringify(intent), JSON.stringify(selectors))),
|
package/dist/types.js
CHANGED
|
@@ -1,10 +1 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The shapes a consumer writes and the shapes they get back.
|
|
3
|
-
*
|
|
4
|
-
* **Declarations only.** The derivation is Rust, reached through WebAssembly, so
|
|
5
|
-
* what a JavaScript consumer needs from this package is the vocabulary rather
|
|
6
|
-
* than the solver. A type is erased at build time, so nothing here is a second
|
|
7
|
-
* implementation of anything: it cannot drift into disagreeing with the engine
|
|
8
|
-
* about an *answer*, only about a *field name*, which is what is compared.
|
|
9
|
-
*/
|
|
10
1
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-theme",
|
|
3
3
|
"description": "Theme derivation engine. Computes a complete, contrast-guaranteed token set from intent inputs.",
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
],
|
|
25
25
|
"sideEffects": false,
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "tsc -p tsconfig.json",
|
|
27
|
+
"build": "tsc -p tsconfig.json && tsc -p tsconfig.types.json",
|
|
28
28
|
"test": "cargo test -p fusion-helix-theme --manifest-path ../../Cargo.toml",
|
|
29
29
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
30
30
|
"wasm": "node scripts/build-wasm.mjs",
|