takumi-js 1.0.0 → 1.0.1
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 +99 -9
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,16 +1,105 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img src="https://takumi.kane.tw/logo.svg" alt="Takumi" width="64" />
|
|
3
3
|
|
|
4
|
-
#
|
|
4
|
+
# takumi-js
|
|
5
5
|
|
|
6
|
-
**
|
|
7
|
-
OG cards, banners, and lightweight animations from one Rust engine
|
|
6
|
+
**All-in-one Takumi package for Node.js and WebAssembly runtimes.**
|
|
7
|
+
OG cards, banners, and lightweight animations from one Rust engine — no headless browser required.
|
|
8
8
|
|
|
9
9
|
[Documentation](https://takumi.kane.tw/docs/) · [Playground](https://takumi.kane.tw/playground)
|
|
10
10
|
|
|
11
11
|
</div>
|
|
12
12
|
|
|
13
|
-
##
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
bun add takumi-js
|
|
17
|
+
# or
|
|
18
|
+
npm install takumi-js
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Quick start
|
|
22
|
+
|
|
23
|
+
```tsx
|
|
24
|
+
import { render } from "takumi-js";
|
|
25
|
+
import { writeFile } from "node:fs/promises";
|
|
26
|
+
|
|
27
|
+
const image = await render(
|
|
28
|
+
<div tw="w-full h-full flex items-center justify-center bg-gradient-to-b from-blue-100 to-red-50">
|
|
29
|
+
<h1 tw="text-6xl font-bold">Hello from Takumi</h1>
|
|
30
|
+
</div>,
|
|
31
|
+
{ width: 1200, height: 630 },
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
await writeFile("./output.png", image);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Entry points
|
|
38
|
+
|
|
39
|
+
| Import | Description |
|
|
40
|
+
| :------------------------ | :---------------------------------------------------------------------- |
|
|
41
|
+
| `takumi-js` | `render()` + all shared types |
|
|
42
|
+
| `takumi-js/response` | `ImageResponse` class — drop-in compatible with `next/og` |
|
|
43
|
+
| `takumi-js/node` | Re-exports `@takumi-rs/core` (native napi-rs bindings) |
|
|
44
|
+
| `takumi-js/wasm` | Re-exports `@takumi-rs/wasm` + `init()` for manual WASM initialization |
|
|
45
|
+
| `takumi-js/helpers` | Node tree utilities (`fromJsx`, `fromHtml`, `fetchResources`, …) |
|
|
46
|
+
| `takumi-js/helpers/jsx` | `fromJsx` — convert a React element to a Takumi node tree + stylesheets |
|
|
47
|
+
| `takumi-js/helpers/emoji` | `extractEmojis` — replace emoji characters with image nodes |
|
|
48
|
+
|
|
49
|
+
## Runtime detection
|
|
50
|
+
|
|
51
|
+
`takumi-js` automatically selects the best backend:
|
|
52
|
+
|
|
53
|
+
- **Node.js** → native `@takumi-rs/core` (napi-rs)
|
|
54
|
+
- **Next.js Edge / Cloudflare Workers / browsers** → `@takumi-rs/wasm`
|
|
55
|
+
|
|
56
|
+
You can override this by passing a `module` option to `render()` or using `takumi-js/wasm` directly.
|
|
57
|
+
|
|
58
|
+
## Examples
|
|
59
|
+
|
|
60
|
+
### `next/og`-compatible API route
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { ImageResponse } from "takumi-js/response";
|
|
64
|
+
|
|
65
|
+
export function GET() {
|
|
66
|
+
return new ImageResponse(
|
|
67
|
+
<div tw="w-full h-full flex items-center justify-center bg-gradient-to-b from-blue-100 to-red-50">
|
|
68
|
+
<h1 tw="text-6xl font-bold">Hello from Takumi</h1>
|
|
69
|
+
</div>,
|
|
70
|
+
{ width: 1200, height: 630 },
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Animated WebP
|
|
76
|
+
|
|
77
|
+
```tsx
|
|
78
|
+
import { Renderer } from "takumi-js/node";
|
|
79
|
+
import { fromJsx } from "takumi-js/helpers/jsx";
|
|
80
|
+
import { writeFile } from "node:fs/promises";
|
|
81
|
+
|
|
82
|
+
const renderer = new Renderer();
|
|
83
|
+
|
|
84
|
+
const { node, stylesheets } = await fromJsx(
|
|
85
|
+
<div tw="w-full h-full flex items-center justify-center">
|
|
86
|
+
<div tw="w-32 h-32 bg-blue-500 animate-spin rounded-lg" />
|
|
87
|
+
</div>,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
const animation = await renderer.renderAnimation({
|
|
91
|
+
width: 400,
|
|
92
|
+
height: 400,
|
|
93
|
+
fps: 30,
|
|
94
|
+
format: "webp",
|
|
95
|
+
stylesheets,
|
|
96
|
+
scenes: [{ durationMs: 1000, node }],
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
await writeFile("./output.webp", animation);
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Bun server
|
|
14
103
|
|
|
15
104
|
```tsx
|
|
16
105
|
import { ImageResponse } from "takumi-js/response";
|
|
@@ -20,14 +109,15 @@ serve({
|
|
|
20
109
|
fetch() {
|
|
21
110
|
return new ImageResponse(
|
|
22
111
|
<div tw="w-full h-full flex items-center justify-center bg-[linear-gradient(to_bottom,#dbf4ff,#fff1f1)]">
|
|
23
|
-
<h1 tw="text-6xl font-bold">Hello from Takumi
|
|
112
|
+
<h1 tw="text-6xl font-bold">Hello from Takumi 👋</h1>
|
|
24
113
|
</div>,
|
|
25
|
-
{
|
|
26
|
-
width: 1200,
|
|
27
|
-
height: 630,
|
|
28
|
-
},
|
|
114
|
+
{ width: 1200, height: 630 },
|
|
29
115
|
);
|
|
30
116
|
},
|
|
31
117
|
port: 3000,
|
|
32
118
|
});
|
|
33
119
|
```
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
MIT or Apache-2.0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "takumi-js",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "All-in-one Takumi package for Node.js and WebAssembly runtimes.",
|
|
5
5
|
"license": "(MIT OR Apache-2.0)",
|
|
6
6
|
"author": {
|
|
@@ -69,9 +69,9 @@
|
|
|
69
69
|
"test:bundlers": "bun test tests/bundlers.test.ts"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@takumi-rs/core": "1.0.
|
|
73
|
-
"@takumi-rs/helpers": "1.0.
|
|
74
|
-
"@takumi-rs/wasm": "1.0.
|
|
72
|
+
"@takumi-rs/core": "1.0.1",
|
|
73
|
+
"@takumi-rs/helpers": "1.0.1",
|
|
74
|
+
"@takumi-rs/wasm": "1.0.1"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@types/bun": "catalog:",
|