feat: scaffold Svelte app with shared types and scale calculation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4284f2533b
commit
a39122c504
12 files changed
+1491
No files matched your search
@@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Scrap Tracer</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
Generated
+1369
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "scrap-tracer",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-check --tsconfig ./tsconfig.json",
|
||||
"test": "vitest run"
|
||||
},
|
||||
"dependencies": {
|
||||
"@techstark/opencv-js": "4.12.0-release.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/vite-plugin-svelte": "^7.3.1",
|
||||
"@tsconfig/svelte": "^5.0.8",
|
||||
"@types/node": "^22.20.5",
|
||||
"jpeg-js": "^0.4.4",
|
||||
"svelte": "^5.57.2",
|
||||
"svelte-check": "^4.7.6",
|
||||
"typescript": "^6.0.3",
|
||||
"vite": "^8.3.4",
|
||||
"vitest": "^5.0.4"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<script lang="ts"></script>
|
||||
|
||||
<h1>Scrap Tracer</h1>
|
||||
@@ -0,0 +1,7 @@
|
||||
import type { Point } from './types';
|
||||
|
||||
export function scaleFromLine(a: Point, b: Point, lengthMm: number): number | null {
|
||||
const lengthPx = Math.hypot(b.x - a.x, b.y - a.y);
|
||||
if (!(lengthMm > 0) || lengthPx < 1) return null;
|
||||
return lengthPx / lengthMm;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
export type Point = { x: number; y: number };
|
||||
|
||||
/** A piece outline: one outer ring plus hole rings. Units depend on the pipeline stage (px or mm). */
|
||||
export type Shape = { outer: Point[]; holes: Point[][] };
|
||||
|
||||
/** RGBA pixels, structurally compatible with ImageData. */
|
||||
export type RasterImage = { width: number; height: number; data: Uint8ClampedArray<ArrayBuffer> };
|
||||
|
||||
export type DetectParams = {
|
||||
threshold: number;
|
||||
invert: boolean;
|
||||
seed: Point | null;
|
||||
/** Negative shrinks the piece (and grows holes). */
|
||||
marginPx: number;
|
||||
};
|
||||
@@ -0,0 +1,4 @@
|
||||
import { mount } from 'svelte';
|
||||
import App from './App.svelte';
|
||||
|
||||
mount(App, { target: document.getElementById('app')! });
|
||||
@@ -0,0 +1,3 @@
|
||||
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
export default { preprocess: vitePreprocess({ script: true }) };
|
||||
@@ -0,0 +1,18 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { scaleFromLine } from '../src/lib/scale';
|
||||
|
||||
describe('scaleFromLine', () => {
|
||||
it('returns pixels per mm', () => {
|
||||
expect(scaleFromLine({ x: 0, y: 0 }, { x: 300, y: 400 }, 100)).toBeCloseTo(5);
|
||||
});
|
||||
|
||||
it('rejects a non-positive or missing length', () => {
|
||||
expect(scaleFromLine({ x: 0, y: 0 }, { x: 100, y: 0 }, 0)).toBeNull();
|
||||
expect(scaleFromLine({ x: 0, y: 0 }, { x: 100, y: 0 }, -5)).toBeNull();
|
||||
expect(scaleFromLine({ x: 0, y: 0 }, { x: 100, y: 0 }, NaN)).toBeNull();
|
||||
});
|
||||
|
||||
it('rejects a line shorter than one pixel', () => {
|
||||
expect(scaleFromLine({ x: 10, y: 10 }, { x: 10.5, y: 10 }, 100)).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"extends": "@tsconfig/svelte/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
||||
"types": ["node"],
|
||||
"strict": true,
|
||||
"noEmit": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"isolatedModules": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.svelte", "tests/**/*.ts", "vite.config.ts"]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [svelte()],
|
||||
// Rune modules must compile for the browser runtime under Vitest too.
|
||||
resolve: process.env.VITEST ? { conditions: ['browser'] } : undefined,
|
||||
build: { chunkSizeWarningLimit: 12000 },
|
||||
test: {
|
||||
environment: 'node',
|
||||
include: ['tests/**/*.test.ts'],
|
||||
testTimeout: 30000,
|
||||
hookTimeout: 60000,
|
||||
},
|
||||
});
|
||||
Reference in new issue
Block a user