@weft-js/plugin-surface-keel 0.1.1 → 0.1.3
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 +312 -3
- package/package.json +12 -3
- package/src/index.d.ts +5 -1
- package/src/index.mjs +20 -5
- package/src/runtime.mjs +6 -2
- package/vendor/README.md +7 -4
- package/vendor/keel-render/core-primitives.mjs +478 -0
- package/vendor/keel-render/effects-world.mjs +439 -0
- package/vendor/keel-render/indexed-render.mjs +516 -0
- package/vendor/keel-render/pixel-raster.mjs +512 -0
- package/vendor/keel-render/render-passes.mjs +530 -0
- package/vendor/keel-render/renderer-api.mjs +121 -0
- package/vendor/keel-render.mjs +1 -2268
- package/vendor/keel-theme/codec-runtime.mjs +549 -0
- package/vendor/keel-theme/collection-codecs.mjs +360 -0
- package/vendor/keel-theme/color-font.mjs +471 -0
- package/vendor/keel-theme/glyph-theme.mjs +529 -0
- package/vendor/keel-theme/icon-schema.mjs +540 -0
- package/vendor/keel-theme/scalar-codecs.mjs +535 -0
- package/vendor/keel-theme/schema-codec.mjs +515 -0
- package/vendor/keel-theme/schema-theme.mjs +533 -0
- package/vendor/keel-theme.mjs +1 -3571
package/README.md
CHANGED
|
@@ -1,9 +1,318 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://github.com/Ravonus/weft">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/Ravonus/weft/main/site/public/logo.svg" width="88" height="88" alt="Weft">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
2
6
|
|
|
3
|
-
>
|
|
7
|
+
<h1 align="center">@weft-js/plugin-surface-keel</h1>
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
<p align="center">
|
|
10
|
+
<strong>KEEL's WebGL2 pixel renderer as a Weft surface kind: <code>kind: 'keel-pixel'</code>.</strong><br>
|
|
11
|
+
A fixed low-resolution target scaled up with nearest sampling, plus KEEL's seeded theme recipes as palettes and CSS variables.
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
<p align="center">
|
|
15
|
+
<a href="https://www.npmjs.com/package/@weft-js/plugin-surface-keel"><img src="https://img.shields.io/npm/v/@weft-js/plugin-surface-keel?color=145c3c&label=npm" alt="npm version"></a>
|
|
16
|
+
<a href="https://github.com/Ravonus/weft/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-145c3c" alt="MIT license"></a>
|
|
17
|
+
<a href="https://github.com/Ravonus/weft/actions"><img src="https://img.shields.io/github/actions/workflow/status/Ravonus/weft/quality.yml?branch=main&label=checks" alt="checks"></a>
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="#quick-start">Quick start</a> ·
|
|
22
|
+
<a href="https://github.com/Ravonus/weft/tree/main/docs">Docs</a> ·
|
|
23
|
+
<a href="https://github.com/Ravonus/weft/tree/main/examples">Examples</a> ·
|
|
24
|
+
<a href="https://github.com/Ravonus/weft/blob/main/CHANGELOG.md">Changelog</a> ·
|
|
25
|
+
<a href="https://github.com/Ravonus/weft">GitHub</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
> [!IMPORTANT]
|
|
29
|
+
> **Early release (0.1.x).** APIs can change between minor versions. Pin the version and read the
|
|
30
|
+
> [changelog](https://github.com/Ravonus/weft/blob/main/CHANGELOG.md) before you upgrade.
|
|
31
|
+
|
|
32
|
+
Weft's surfaces (`@weft-js/core/surface`) are canvas or WebGL views that sit in layout like any other child: `setup`
|
|
33
|
+
runs once on the client, props stay live, and nothing around them re-renders. Core has two built-in kinds, `canvas2d`
|
|
34
|
+
and `webgl2`. This plugin adds a third, `keel-pixel`, through the `surface.renderer@1` slot. A `keel-pixel` surface gets
|
|
35
|
+
`s.px`, KEEL's `PixelRenderer`, which owns the GL context and draws a palette-indexed 3D world into a small fixed
|
|
36
|
+
target. It also exports KEEL's theme recipes, which turn a seed into palette ramps and `--keel-*` CSS variables.
|
|
37
|
+
|
|
38
|
+
The renderer and theme code are vendored from KEEL's engine (keel-engine) at a pinned commit; see
|
|
39
|
+
[Vendored code](#vendored-code).
|
|
40
|
+
|
|
41
|
+
## Highlights
|
|
42
|
+
|
|
43
|
+
- **A new surface kind, nothing else to wire.** `keel()` in `plugins` registers `keel-pixel`; `defineSurface({ kind:
|
|
44
|
+
'keel-pixel', pixel: { width, height } })` uses it.
|
|
45
|
+
- **Loaded only where it's used.** The renderer sits behind the slot's `import()`, so only pages that mount a
|
|
46
|
+
`keel-pixel` surface download it.
|
|
47
|
+
- **Fixed pixel target.** `pixel: { width, height }` renders at that resolution and scales up by an integer with nearest
|
|
48
|
+
sampling.
|
|
49
|
+
- **Seeded themes.** `recipeTheme({ seed, culture })` gives the same theme every time for the same recipe: palette ramps,
|
|
50
|
+
frame, type, spacing and motion. `themeTokens(theme, scale)` turns it into CSS variables.
|
|
51
|
+
- **KEEL's UI styles.** `@weft-js/plugin-surface-keel/styles.css` styles `[data-keel-theme]`, `.keel-panel` and
|
|
52
|
+
`.keel-button` from those variables, and drops animation under `prefers-reduced-motion`.
|
|
53
|
+
- **Typed `s.px`.** The package augments `@weft-js/core/surface`'s `SurfaceKinds`, so `s.px` is typed inside `setup`.
|
|
54
|
+
- **Clean teardown.** When the surface goes, the WebGL context is released with `WEBGL_lose_context`.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
6
57
|
|
|
7
58
|
```bash
|
|
59
|
+
# npm
|
|
8
60
|
npm install @weft-js/plugin-surface-keel
|
|
61
|
+
|
|
62
|
+
# pnpm
|
|
63
|
+
pnpm add @weft-js/plugin-surface-keel
|
|
64
|
+
|
|
65
|
+
# bun
|
|
66
|
+
bun add @weft-js/plugin-surface-keel
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Or let the `weft` CLI install it and add it to `weft.config.ts` in one step:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npx weft add surface-keel
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The
|
|
76
|
+
package has no `/plugin` entry and no default export, so `weft add` writes `import { keel } from
|
|
77
|
+
'@weft-js/plugin-surface-keel'` and adds `keel()` to `plugins`.
|
|
78
|
+
|
|
79
|
+
**What it needs:** a browser with WebGL2. There's no server or build-time dependency. If you draw canvas text with
|
|
80
|
+
`s.text()` on a surface, add `text()` from `@weft-js/text` too (the `text.measure` slot), as the demo does.
|
|
81
|
+
|
|
82
|
+
## Quick start
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// weft.config.ts
|
|
86
|
+
import { defineConfig } from '@weft-js/core/config'
|
|
87
|
+
import { text } from '@weft-js/text'
|
|
88
|
+
import { keel } from '@weft-js/plugin-surface-keel'
|
|
89
|
+
|
|
90
|
+
export default defineConfig({ plugins: [text(), keel()] })
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
```tsx
|
|
94
|
+
// src/routes/scene.tsx
|
|
95
|
+
import { defineSurface, Surface } from '@weft-js/core/surface'
|
|
96
|
+
import {
|
|
97
|
+
recipeTheme,
|
|
98
|
+
themeTokens,
|
|
99
|
+
} from '@weft-js/plugin-surface-keel/theme'
|
|
100
|
+
import '@weft-js/plugin-surface-keel/styles.css'
|
|
101
|
+
|
|
102
|
+
const theme = recipeTheme({
|
|
103
|
+
seed: 'keel/react-demo',
|
|
104
|
+
culture: 'clean',
|
|
105
|
+
})
|
|
106
|
+
const css = Object.entries(themeTokens(theme, 2))
|
|
107
|
+
.map(([k, v]) => `${k}:${v}`)
|
|
108
|
+
.join(';')
|
|
109
|
+
|
|
110
|
+
// Palette ramps are packed RGB numbers; the renderer takes [r, g, b]
|
|
111
|
+
// triples and named ranges.
|
|
112
|
+
const colours = [
|
|
113
|
+
...theme.palette.surface,
|
|
114
|
+
...theme.palette.accent,
|
|
115
|
+
].map((c: number) => [c & 255, (c >>> 8) & 255, (c >>> 16) & 255])
|
|
116
|
+
const ramps = {
|
|
117
|
+
surface: [0, theme.palette.surface.length],
|
|
118
|
+
accent: [theme.palette.surface.length, theme.palette.accent.length],
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export const Scene = defineSurface({
|
|
122
|
+
name: 'keel-scene',
|
|
123
|
+
kind: 'keel-pixel',
|
|
124
|
+
pixel: { width: 256, height: 144 },
|
|
125
|
+
fps: 30,
|
|
126
|
+
setup(s) {
|
|
127
|
+
s.px.setPalette(colours, ramps)
|
|
128
|
+
s.px.setMaterials([{ ramp: 'surface' }, { ramp: 'accent' }])
|
|
129
|
+
s.px.setWorld({
|
|
130
|
+
boxes: [
|
|
131
|
+
{ c: [0, -0.5, 0], h: [5, 0.5, 5], mat: 0 },
|
|
132
|
+
{ c: [0, 1, 0], h: [0.75, 1, 0.75], mat: 1 },
|
|
133
|
+
],
|
|
134
|
+
})
|
|
135
|
+
s.px.setStyle({ screen: 4 })
|
|
136
|
+
s.frame((t) =>
|
|
137
|
+
s.px.render({
|
|
138
|
+
eye: [Math.sin(t.seconds) * 5, 3, Math.cos(t.seconds) * 5],
|
|
139
|
+
target: [0, 1, 0],
|
|
140
|
+
time: t.seconds,
|
|
141
|
+
}),
|
|
142
|
+
)
|
|
143
|
+
},
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
export default function Page() {
|
|
147
|
+
return (
|
|
148
|
+
<div
|
|
149
|
+
data-keel-theme={theme.key}
|
|
150
|
+
style={css}
|
|
151
|
+
>
|
|
152
|
+
<Surface
|
|
153
|
+
use={Scene}
|
|
154
|
+
label="A box on a floor, orbited by the camera"
|
|
155
|
+
style="max-width:640px"
|
|
156
|
+
/>
|
|
157
|
+
</div>
|
|
158
|
+
)
|
|
159
|
+
}
|
|
9
160
|
```
|
|
161
|
+
|
|
162
|
+
This is the package's own demo (`demo/KeelDemo.tsx`, a port of keel-engine's React scaffold demo), trimmed. The camera
|
|
163
|
+
orbits on the shared surface clock, so `clock.pause()` from `@weft-js/core/surface` stops it, and under
|
|
164
|
+
`prefers-reduced-motion: reduce` it starts paused.
|
|
165
|
+
|
|
166
|
+
## How it plugs into Weft
|
|
167
|
+
|
|
168
|
+
| Piece | Detail |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| Slot | `surface.renderer@1`, keyed, client side only. This plugin provides the key `keel-pixel`. |
|
|
171
|
+
| Provider | `renderer` from `@weft-js/plugin-surface-keel/runtime`. Its `context(canvas, def)` creates the `PixelRenderer` and returns `{ fields: { px }, dispose }`. |
|
|
172
|
+
| Loading | Core's surface mount handles `canvas2d` and `webgl2` itself; any other kind is loaded through `import('weft:slot/surface.renderer')`. If loading fails, the error is logged and the host element gets `data-surface-error="keel-pixel"`. |
|
|
173
|
+
| Namespace | `surface-keel/`. |
|
|
174
|
+
| Agent notes | `kind: 'keel-pixel'` needs `pixel: { width, height }`; `s.px` is KEEL's `PixelRenderer`; palettes come from `recipeTheme()`. |
|
|
175
|
+
|
|
176
|
+
Everything else about a surface is core's: `<Surface>` takes `use`, your props, `aspect` (default `2/1`), `label`
|
|
177
|
+
(required) or `decorative`, `class` and `style`, and the server renders a sized placeholder so nothing shifts when the
|
|
178
|
+
canvas mounts. `weft docs surface` covers it.
|
|
179
|
+
|
|
180
|
+
## `defineSurface` with `kind: 'keel-pixel'`
|
|
181
|
+
|
|
182
|
+
| Field | Type | Default | What it does |
|
|
183
|
+
| --- | --- | --- | --- |
|
|
184
|
+
| `kind` | `'keel-pixel'` | | Selects this renderer. |
|
|
185
|
+
| `pixel` | `{ width: number, height: number }` | required | The fixed render target. Without it, mounting throws ``surface `<name>`: `keel-pixel` needs `pixel: { width, height }` ``. |
|
|
186
|
+
| `fps` | `number` | `60` | Core's frame cap for `s.frame`. |
|
|
187
|
+
| `setup(s, props)` | function | | Runs once on the client. `s.px` is the renderer; `s.frame`, `s.draw`, `s.size`, `s.el` and `s.text` work as for any surface. |
|
|
188
|
+
|
|
189
|
+
### `s.px`: the renderer
|
|
190
|
+
|
|
191
|
+
The typed part of KEEL's `PixelRenderer` (`src/vendor-types.d.ts`). The rest of the vendored API is reachable but
|
|
192
|
+
untyped.
|
|
193
|
+
|
|
194
|
+
| Method | What it takes |
|
|
195
|
+
| --- | --- |
|
|
196
|
+
| `setPalette(colours, ramps)` | `colours`: `[r, g, b]` triples. `ramps`: named `[start, length]` ranges into `colours`. |
|
|
197
|
+
| `setMaterials(materials)` | `{ ramp: string }[]`: material `i` shades from the named ramp. |
|
|
198
|
+
| `setWorld(world)` | The scene, for example `{ boxes: [{ c, h, mat }] }` (centre, half-extents, material index). |
|
|
199
|
+
| `setStyle(style)` | Render style, for example `{ screen: 4 }`. |
|
|
200
|
+
| `render(view)` | One frame: `{ eye, target, time }`. Call it from `s.frame`. |
|
|
201
|
+
|
|
202
|
+
## Themes
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import {
|
|
206
|
+
recipeTheme,
|
|
207
|
+
themeTokens,
|
|
208
|
+
} from '@weft-js/plugin-surface-keel/theme'
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
| Function | Signature | What it returns |
|
|
212
|
+
| --- | --- | --- |
|
|
213
|
+
| `recipeTheme(recipe?)` | `{ seed?, culture?, pins? }` | A theme: `key`, `palette`, and frame, type, spacing and motion. The same recipe gives the same theme. |
|
|
214
|
+
| `themeTokens(theme, scale?)` | theme, integer scale | `--keel-*` CSS variables at that scale; at scale 2, `--keel-px` is `2px`. |
|
|
215
|
+
|
|
216
|
+
`palette` (type `Palette`) has `tone`, ramps `surface`, `ink`, `accent`, `good`, `warn`, `bad` (packed RGB numbers),
|
|
217
|
+
`team`, `outline`, `onAccent`, and `hues: { surface, accent }`.
|
|
218
|
+
|
|
219
|
+
`styles.css` reads `--keel-font`, `--keel-body`, `--keel-ink`, `--keel-surface`, `--keel-border`, `--keel-outline`,
|
|
220
|
+
`--keel-pad`, `--keel-on-accent`, `--keel-accent` and `--keel-px`, and sets `image-rendering: pixelated` on canvases inside
|
|
221
|
+
`.keel-canvas`.
|
|
222
|
+
|
|
223
|
+
## API reference
|
|
224
|
+
|
|
225
|
+
| Export | Entry | What it is |
|
|
226
|
+
| --- | --- | --- |
|
|
227
|
+
| `keel()` | `@weft-js/plugin-surface-keel` | The plugin for `weft.config.ts`. |
|
|
228
|
+
| `recipeTheme`, `themeTokens` | `@weft-js/plugin-surface-keel/theme` | KEEL's theme recipes (types come from the main entry's declarations). |
|
|
229
|
+
| `renderer` | `@weft-js/plugin-surface-keel/runtime` | The `surface.renderer@1` provider. Loaded by the slot; you don't import it yourself. |
|
|
230
|
+
| `styles.css` | `@weft-js/plugin-surface-keel/styles.css` | KEEL's UI styles, driven by the theme's CSS variables. |
|
|
231
|
+
| `SurfaceKinds['keel-pixel']` | type augmentation of `@weft-js/core/surface` | Makes `s.px` a `PixelRenderer` in `setup`. |
|
|
232
|
+
|
|
233
|
+
## Recipes
|
|
234
|
+
|
|
235
|
+
**A play/pause button beside the scene.** The clock is shared, and `clock.playing` is a box the button reads:
|
|
236
|
+
|
|
237
|
+
```tsx
|
|
238
|
+
import { clock } from '@weft-js/core/surface'
|
|
239
|
+
|
|
240
|
+
export function Controls() {
|
|
241
|
+
return (
|
|
242
|
+
<section
|
|
243
|
+
class="keel-panel"
|
|
244
|
+
aria-label="Scene controls"
|
|
245
|
+
>
|
|
246
|
+
<button
|
|
247
|
+
class="keel-button"
|
|
248
|
+
type="button"
|
|
249
|
+
onClick={() =>
|
|
250
|
+
clock.playing.value ? clock.pause() : clock.play()
|
|
251
|
+
}
|
|
252
|
+
>
|
|
253
|
+
{clock.playing.value ? 'PAUSE' : 'PLAY'}
|
|
254
|
+
</button>
|
|
255
|
+
</section>
|
|
256
|
+
)
|
|
257
|
+
}
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**A deterministic frame for a screenshot.** `clock.seek(seconds)` paints every animated surface at that time.
|
|
261
|
+
|
|
262
|
+
## Limits
|
|
263
|
+
|
|
264
|
+
- Client only, and WebGL2 only. The server renders the sized placeholder.
|
|
265
|
+
- `pixel` is required: there is no resolution-following mode for this kind.
|
|
266
|
+
- Only the five `PixelRenderer` methods above are typed.
|
|
267
|
+
- The vendored engine is a snapshot. New KEEL features arrive only when the vendor files are regenerated from a newer
|
|
268
|
+
pin.
|
|
269
|
+
|
|
270
|
+
## Troubleshooting
|
|
271
|
+
|
|
272
|
+
| Symptom | Cause and fix |
|
|
273
|
+
| --- | --- |
|
|
274
|
+
| The surface stays a placeholder and has `data-surface-error="keel-pixel"` | The renderer failed to load or set up; the browser console has the error. Check that `keel()` is in `plugins`, and that the browser has WebGL2. |
|
|
275
|
+
| ``surface `<name>`: `keel-pixel` needs `pixel: { width, height }` `` | Add `pixel` to the definition. |
|
|
276
|
+
| P101 for `text.measure` | `s.text()` on a canvas surface needs `text()` from `@weft-js/text` in `plugins`. |
|
|
277
|
+
| Blurry pixels | Put the canvas inside `.keel-canvas` and import `styles.css`, or set `image-rendering: pixelated` yourself. |
|
|
278
|
+
|
|
279
|
+
## Vendored code
|
|
280
|
+
|
|
281
|
+
`vendor/` is generated by `scripts/vendor.mjs` from keel-engine commit `4bcccc7` and must not be edited by hand:
|
|
282
|
+
|
|
283
|
+
| File | From keel-engine |
|
|
284
|
+
| --- | --- |
|
|
285
|
+
| `keel-render.mjs` (and `keel-render/`) | `createPixelRenderer` from `packages/render` |
|
|
286
|
+
| `keel-theme.mjs` (and `keel-theme/`) | `recipeTheme` and `themeTokens` from `packages/react/src/design.ts` |
|
|
287
|
+
| `keel-styles.css` | `packages/react/src/styles.css` |
|
|
288
|
+
|
|
289
|
+
The checked patches in `scripts/vendor/` move the pinned bundles into local modules. `pnpm --filter
|
|
290
|
+
@weft-js/plugin-surface-keel vendor` regenerates them from a keel-engine checkout: `~/dev/keel-engine`, or a path
|
|
291
|
+
passed as its argument. It refuses a source without the pinned commit. The test that regenerates them reads
|
|
292
|
+
`KEEL_ENGINE`, and skips without a checkout.
|
|
293
|
+
|
|
294
|
+
## Related packages
|
|
295
|
+
|
|
296
|
+
| Package | What it is |
|
|
297
|
+
| --- | --- |
|
|
298
|
+
| [`@weft-js/core`](https://www.npmjs.com/package/@weft-js/core) | `defineSurface`, `<Surface>` and the clock (`@weft-js/core/surface`). |
|
|
299
|
+
| [`@weft-js/text`](https://www.npmjs.com/package/@weft-js/text) | The `text.measure` slot that `s.text()` on a canvas needs. |
|
|
300
|
+
| [`@weft-js/cli`](https://www.npmjs.com/package/@weft-js/cli) | `weft add surface-keel`, `weft docs surface`, `weft surfaces --json`. |
|
|
301
|
+
|
|
302
|
+
## Contributing
|
|
303
|
+
|
|
304
|
+
See [CONTRIBUTING.md](https://github.com/Ravonus/weft/blob/main/CONTRIBUTING.md). From the repository root:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
# Plugin contract, themes, vendor checks
|
|
308
|
+
pnpm --filter @weft-js/plugin-surface-keel test
|
|
309
|
+
# Builds demo/ and checks pixels in Chrome and WebKit
|
|
310
|
+
pnpm --filter @weft-js/plugin-surface-keel test:e2e
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The end-to-end run builds `demo/` with `@weft-js/core/vite` and needs `@weft-js/text` built first.
|
|
314
|
+
|
|
315
|
+
## License
|
|
316
|
+
|
|
317
|
+
[MIT](https://github.com/Ravonus/weft/blob/main/LICENSE). The vendored KEEL code is MIT too; its licence is kept
|
|
318
|
+
byte-for-byte in [`vendor/LICENSE`](https://github.com/Ravonus/weft/blob/main/packages/plugin-surface-keel/vendor/LICENSE).
|
package/package.json
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weft-js/plugin-surface-keel",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "@weft-js/plugin-surface-keel: the `keel-pixel` surface kind (surface.renderer@1): KEEL's WebGL2 pixel renderer and theme recipes.",
|
|
5
5
|
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/Ravonus/weft.git",
|
|
9
|
+
"directory": "packages/plugin-surface-keel"
|
|
10
|
+
},
|
|
11
|
+
"homepage": "https://github.com/Ravonus/weft/tree/main/packages/plugin-surface-keel#readme",
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/Ravonus/weft/issues"
|
|
14
|
+
},
|
|
6
15
|
"type": "module",
|
|
7
16
|
"exports": {
|
|
8
17
|
".": {
|
|
@@ -17,7 +26,7 @@
|
|
|
17
26
|
"./styles.css": "./vendor/keel-styles.css"
|
|
18
27
|
},
|
|
19
28
|
"peerDependencies": {
|
|
20
|
-
"@weft-js/core": "^0.1.
|
|
29
|
+
"@weft-js/core": "^0.1.3"
|
|
21
30
|
},
|
|
22
31
|
"engines": {
|
|
23
32
|
"node": ">=26"
|
|
@@ -34,4 +43,4 @@
|
|
|
34
43
|
"publishConfig": {
|
|
35
44
|
"access": "public"
|
|
36
45
|
}
|
|
37
|
-
}
|
|
46
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -5,7 +5,11 @@ import type { Palette, PixelRenderer } from './vendor-types'
|
|
|
5
5
|
export declare const keel: () => PluginEntry
|
|
6
6
|
|
|
7
7
|
/** `{ seed, culture, pins }` → KEEL's theme: palette ramps, frame, type, spacing and motion. */
|
|
8
|
-
export declare function recipeTheme(recipe?: {
|
|
8
|
+
export declare function recipeTheme(recipe?: {
|
|
9
|
+
seed?: string
|
|
10
|
+
culture?: string
|
|
11
|
+
pins?: Record<string, unknown>
|
|
12
|
+
}): { key: string; palette: Palette; [k: string]: unknown }
|
|
9
13
|
/** A theme as `--keel-*` CSS variables at an integer scale. */
|
|
10
14
|
export declare function themeTokens(theme: unknown, scale?: number): Record<string, string>
|
|
11
15
|
|
package/src/index.mjs
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
//
|
|
2
|
-
// stays behind the slot's `import()` and only pages that mount a `keel-pixel` surface load it.
|
|
1
|
+
// KEEL's renderer stays behind the slot's `import()` so only pages that mount it load it.
|
|
3
2
|
import { definePlugin, defineSlot, provide } from '@weft-js/core/plugin'
|
|
4
3
|
|
|
5
|
-
const renderer = defineSlot({
|
|
4
|
+
const renderer = defineSlot({
|
|
5
|
+
id: 'surface.renderer',
|
|
6
|
+
version: 1,
|
|
7
|
+
cardinality: 'keyed',
|
|
8
|
+
sides: ['client'],
|
|
9
|
+
})
|
|
6
10
|
|
|
7
11
|
export const keel = definePlugin({
|
|
8
12
|
name: '@weft-js/plugin-surface-keel',
|
|
@@ -10,11 +14,22 @@ export const keel = definePlugin({
|
|
|
10
14
|
weft: '*',
|
|
11
15
|
namespace: 'surface-keel/',
|
|
12
16
|
contribute: () => ({
|
|
13
|
-
provides: [
|
|
17
|
+
provides: [
|
|
18
|
+
provide(renderer, {
|
|
19
|
+
key: 'keel-pixel',
|
|
20
|
+
sides: { client: { module: '@weft-js/plugin-surface-keel/runtime', export: 'renderer' } },
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
14
23
|
agents: {
|
|
15
24
|
title: 'KEEL surfaces (@weft-js/plugin-surface-keel)',
|
|
16
25
|
text: "- `kind: 'keel-pixel'` needs `pixel: { width, height }`. `s.px` is KEEL's `PixelRenderer`: `setPalette`, `setMaterials`, `setWorld`, `render`. Palettes come from `recipeTheme()` in `@weft-js/plugin-surface-keel/theme`.",
|
|
17
26
|
},
|
|
18
|
-
catalog: [
|
|
27
|
+
catalog: [
|
|
28
|
+
{
|
|
29
|
+
name: 'keel',
|
|
30
|
+
import: '@weft-js/plugin-surface-keel',
|
|
31
|
+
summary: 'surface.renderer: keel-pixel',
|
|
32
|
+
},
|
|
33
|
+
],
|
|
19
34
|
}),
|
|
20
35
|
})
|
package/src/runtime.mjs
CHANGED
|
@@ -4,8 +4,12 @@ import { createPixelRenderer } from '../vendor/keel-render.mjs'
|
|
|
4
4
|
/** The surface.renderer@1 provider: `context` makes the surface's `s.px` and undoes it when the surface goes. */
|
|
5
5
|
export const renderer = {
|
|
6
6
|
context(canvas, def) {
|
|
7
|
-
if (!def.pixel)
|
|
7
|
+
if (!def.pixel)
|
|
8
|
+
throw new Error(`surface \`${def.name}\`: \`keel-pixel\` needs \`pixel: { width, height }\``)
|
|
8
9
|
const px = createPixelRenderer(canvas, def.pixel)
|
|
9
|
-
return {
|
|
10
|
+
return {
|
|
11
|
+
fields: { px },
|
|
12
|
+
dispose: () => canvas.getContext('webgl2')?.getExtension('WEBGL_lose_context')?.loseContext(),
|
|
13
|
+
}
|
|
10
14
|
},
|
|
11
15
|
}
|
package/vendor/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# vendor
|
|
2
2
|
|
|
3
|
-
Built by `scripts/vendor.mjs` from keel-engine 4bcccc7 (MIT
|
|
4
|
-
|
|
3
|
+
Built by `scripts/vendor.mjs` from keel-engine 4bcccc7 (MIT; see LICENSE).
|
|
4
|
+
The checked patches move the pinned bundles into local modules. Don't edit generated modules directly.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
The existing LICENSE is preserved byte-for-byte. At the pinned commit, upstream's LICENSE names
|
|
7
|
+
Chad Koslovsky and contributors; the preserved vendored copy names ravonus.
|
|
8
|
+
|
|
9
|
+
- `keel-render.mjs`: `createPixelRenderer` from `packages/render` and its local modules.
|
|
10
|
+
- `keel-theme.mjs`: `recipeTheme` and `themeTokens` from `packages/react/src/design.ts` and their local modules.
|
|
8
11
|
- `keel-styles.css`: `packages/react/src/styles.css`.
|