Files
RecipesCam/docker/frontend/vite.config.ts
T
3dtours 97bdf605e2 web: import the camera's RAW, and grade it like the phone
The studio took JPEG, PNG and HEIC and nothing else, so a photographer's own
negatives never reached it. A RAW now loads the way any other file does —
`isRawName` reads the extension off a 24-entry list, the file goes into OPFS
under one slot (`current_image.raw`, beside `current_image.name`, so a reload
finds it again) and `rawDevelop` runs it through LibRaw-wasm: half size, 16-bit
output, camera white balance and the camera's own 3x3 matrix, in bands of 2M
pixels so a 30MB file never holds a second copy of itself. `example-sony.ARW`
(30.3MB) lands as a 3120x2084 picture, no page error.

DEHAZE joins the FX tab, where Lightroom keeps it: a chip off the same
PARAM_DEFS entry (`dehaze`, 0..10) so nothing new renders chips, and the pass is
the dark channel prior — `atmosphericLight` reads A off a 32x32 draw of the
photo, `DEHAZE_SKSL` takes omega up to 0.95 over a floor of 0.1 — measured at
71.8% of the stage's pixels moved between 0 and 10.

The gradient mask grows the six knobs the phone's has: HIGHLIGHT, SHADOW,
WHITE, BLACK, CLARITY and DEHAZE. The mask's falloff is a smoothstep rather than
a line, and CLARITY/DEHAZE inside a mask get a blurred copy of the photo plus
the air A as a second child of the mask shader — so a mask's clarity is clarity
and not a flat brightness lift. The column shows all nine rulers; CLARITY 9
moves 42.2% of the stage, DEHAZE 9 moves 27.9%.

CLARITY stops reading the whole photo per pixel: the single pass that sampled a
15x15 box 225 times is now the three passes the same math wants — 1x15, then
15x1, then a blend, `orig + (orig - B) * 3.2` — about 30 reads. Both signs work
(77.4% of the stage moves at +10, 79.6% at -10), and the negative branch keeps
its mist as it was.

The pointer reviews a look before it is taken: resting on a PHOTO STYLE chip or
a recipe chip lays that look on the photo while it stays there and gives it back
the moment it leaves — byte-identical, measured on four of them (24.9%, 23.8%,
24.5%, 25.3% of the stage moves on, 0.00% off) — while the recipe, the UNDO
stack and the session stay on the look the click left. A hovered look brings its
colour alone: the masks, the dust spots and the mosaic of the photo being edited
ride along, or a pointer crossing a chip row would rub them off. A PRO sim is
left out, since a hover that showed its look would hand over what the click
gates.

Probes: e2e-raw-verify, e2e-dehaze-mask, e2e-mask-verify, e2e-clarity-verify,
e2e-hover-preview2.
2026-09-26 18:18:22 +07:00

39 lines
1.6 KiB
TypeScript

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { fileURLToPath, URL } from 'node:url';
// The app is shared source with the React Native app: `frameUtils.ts` and
// `skiaImage.ts` import `@shopify/react-native-skia`, and the alias below swaps
// that for the CanvasKit adapter. Same trick the W0 spike used, now for the app.
export default defineConfig({
plugins: [react()],
resolve: {
// onnxruntime-web ships two flavours of its default entry: one with the
// runtime's wasm inlined as a build asset, one that fetches it at runtime.
// This picks the second, so the 28MB binary is served from /wasm/ort/ (see
// scripts/copy-wasm.mjs) instead of being emitted twice into dist.
conditions: ['onnxruntime-web-use-extern-wasm'],
alias: {
'@shopify/react-native-skia': fileURLToPath(new URL('./src/engine/skiaShim.ts', import.meta.url)),
},
},
build: {
target: 'es2022',
// canvaskit-wasm's glue JS is ~2.5MB on its own; the wasm is fetched at
// runtime from /wasm/, never bundled.
chunkSizeWarningLimit: 9000,
},
optimizeDeps: {
// libraw-wasm starts its own worker with `new URL('./worker.js',
// import.meta.url)`. Pre-bundling moves the module into .vite/deps/, where
// that sibling does not exist and the worker never loads. Excluding it keeps
// the package's own relative layout; the production build resolves it
// normally either way.
exclude: ['libraw-wasm'],
},
server: {
port: 5173,
proxy: { '/api': process.env.API_ORIGIN ?? 'http://localhost:3000' },
},
});