AppView in a box as a Vite plugin thing hatk.dev
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

add tsc build step and publish packages as @hatk/hatk and @hatk/oauth-client

Switches hatk from shipping raw TypeScript to compiled JS via tsc.
Renames npm package from hatk to @hatk/hatk (npm blocked the unscoped name).
Updates all codegen templates and path references for the new package name.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

+50 -33
+1
.gitignore
··· 4 4 test-results/ 5 5 .svelte-kit/ 6 6 .DS_Store 7 + dist/
+18 -15
packages/hatk/package.json
··· 1 1 { 2 - "name": "hatk", 2 + "name": "@hatk/hatk", 3 + "version": "0.0.1-alpha.2", 3 4 "bin": { 4 - "hatk": "src/cli.ts" 5 + "hatk": "dist/cli.js" 5 6 }, 6 7 "type": "module", 7 8 "exports": { 8 - "./feeds": "./src/feeds.ts", 9 - "./xrpc": "./src/xrpc.ts", 10 - "./opengraph": "./src/opengraph.ts", 11 - "./labels": "./src/labels.ts", 12 - "./lex-types": "./src/lex-types.ts", 13 - "./xrpc-client": "./src/xrpc-client.ts", 14 - "./views": "./src/views.ts", 15 - "./seed": "./src/seed.ts", 16 - "./setup": "./src/setup.ts", 17 - "./test": "./src/test.ts", 18 - "./test/browser": "./src/test-browser.ts", 19 - "./vite-plugin": "./src/vite-plugin.ts" 9 + "./feeds": "./dist/feeds.js", 10 + "./xrpc": "./dist/xrpc.js", 11 + "./opengraph": "./dist/opengraph.js", 12 + "./labels": "./dist/labels.js", 13 + "./lex-types": "./dist/lex-types.js", 14 + "./xrpc-client": "./dist/xrpc-client.js", 15 + "./views": "./dist/views.js", 16 + "./seed": "./dist/seed.js", 17 + "./setup": "./dist/setup.js", 18 + "./test": "./dist/test.js", 19 + "./test/browser": "./dist/test-browser.js", 20 + "./vite-plugin": "./dist/vite-plugin.js" 20 21 }, 22 + "files": ["dist", "fonts", "public"], 21 23 "scripts": { 22 - "build": "vite build" 24 + "build": "tsc -p tsconfig.build.json", 25 + "prepublishOnly": "npm run build" 23 26 }, 24 27 "dependencies": { 25 28 "@bigmoves/lexicon": "^0.2.1",
+16 -16
packages/hatk/src/cli.ts
··· 136 136 }) 137 137 }) 138 138 `, 139 - label: (name) => `import type { LabelRuleContext } from 'hatk/labels' 139 + label: (name) => `import type { LabelRuleContext } from '@hatk/hatk/labels' 140 140 141 141 export default { 142 142 definition: { ··· 152 152 }, 153 153 } 154 154 `, 155 - og: (name) => `import type { OpengraphContext, OpengraphResult } from 'hatk/opengraph' 155 + og: (name) => `import type { OpengraphContext, OpengraphResult } from '@hatk/hatk/opengraph' 156 156 157 157 export default { 158 158 path: '/og/${name}/:id', ··· 190 190 191 191 const testTemplates: Record<string, (name: string) => string> = { 192 192 feed: (name) => `import { describe, test, expect, beforeAll, afterAll } from 'vitest' 193 - import { createTestContext } from 'hatk/test' 193 + import { createTestContext } from '@hatk/hatk/test' 194 194 195 195 let ctx: Awaited<ReturnType<typeof createTestContext>> 196 196 ··· 210 210 }) 211 211 `, 212 212 xrpc: (name) => `import { describe, test, expect, beforeAll, afterAll } from 'vitest' 213 - import { createTestContext } from 'hatk/test' 213 + import { createTestContext } from '@hatk/hatk/test' 214 214 215 215 let ctx: Awaited<ReturnType<typeof createTestContext>> 216 216 ··· 918 918 COPY . . 919 919 RUN node_modules/.bin/hatk build 920 920 EXPOSE 3000 921 - CMD ["node", "--experimental-strip-types", "--no-warnings", "node_modules/hatk/src/main.ts", "config.yaml"] 921 + CMD ["node", "node_modules/@hatk/hatk/dist/main.js", "config.yaml"] 922 922 `, 923 923 ) 924 924 ··· 1064 1064 writeFileSync( 1065 1065 join(dir, 'vite.config.ts'), 1066 1066 `import { sveltekit } from '@sveltejs/kit/vite' 1067 - import { hatk } from 'hatk/vite-plugin' 1067 + import { hatk } from '@hatk/hatk/vite-plugin' 1068 1068 import { defineConfig } from 'vite' 1069 1069 1070 1070 export default defineConfig({ ··· 1323 1323 const usedWrappers = new Set(entries.filter((e) => e.defType).map((e) => wrapperMap[e.defType!])) 1324 1324 1325 1325 let out = '// Auto-generated from lexicons. Do not edit.\n' 1326 - out += `import type { ${[...usedWrappers].sort().join(', ')}, LexServerParams, Checked, Prettify, StrictArg } from 'hatk/lex-types'\n` 1327 - out += `import type { XrpcContext } from 'hatk/xrpc'\n` 1328 - out += `import { defineFeed as _defineFeed, type FeedResult, type FeedContext, type HydrateContext } from 'hatk/feeds'\n` 1329 - out += `import { seed as _seed, type SeedOpts } from 'hatk/seed'\n` 1326 + out += `import type { ${[...usedWrappers].sort().join(', ')}, LexServerParams, Checked, Prettify, StrictArg } from '@hatk/hatk/lex-types'\n` 1327 + out += `import type { XrpcContext } from '@hatk/hatk/xrpc'\n` 1328 + out += `import { defineFeed as _defineFeed, type FeedResult, type FeedContext, type HydrateContext } from '@hatk/hatk/feeds'\n` 1329 + out += `import { seed as _seed, type SeedOpts } from '@hatk/hatk/seed'\n` 1330 1330 1331 1331 // Emit ALL lexicons as `const ... = {...} as const` (including defs-only) 1332 1332 out += `\n// ─── Lexicon Definitions ────────────────────────────────────────────\n\n` ··· 1493 1493 1494 1494 // Emit Ctx helper for typesafe XRPC handler contexts 1495 1495 out += `\n// ─── XRPC Helpers ───────────────────────────────────────────────────\n\n` 1496 - out += `export type { HydrateContext } from 'hatk/feeds'\n` 1497 - out += `export { InvalidRequestError, NotFoundError } from 'hatk/xrpc'\n` 1496 + out += `export type { HydrateContext } from '@hatk/hatk/feeds'\n` 1497 + out += `export { InvalidRequestError, NotFoundError } from '@hatk/hatk/xrpc'\n` 1498 1498 out += `export type Ctx<K extends keyof XrpcSchema & keyof Registry> = XrpcContext<\n` 1499 1499 out += ` LexServerParams<Registry[K], Registry>,\n` 1500 1500 out += ` RecordRegistry,\n` ··· 1545 1545 if (hasLexDef) { 1546 1546 usedWrappers.add('LexDef') 1547 1547 out = out.replace( 1548 - /import type \{ ([^}]+) \} from 'hatk\/lex-types'/, 1549 - `import type { ${[...usedWrappers].sort().join(', ')}, LexServerParams, Checked, Prettify, StrictArg } from 'hatk/lex-types'`, 1548 + /import type \{ ([^}]+) \} from '@hatk\/hatk\/lex-types'/, 1549 + `import type { ${[...usedWrappers].sort().join(', ')}, LexServerParams, Checked, Prettify, StrictArg } from '@hatk/hatk/lex-types'`, 1550 1550 ) 1551 1551 } 1552 1552 ··· 1667 1667 execSync('npx vite dev', { stdio: 'inherit', cwd: process.cwd() }) 1668 1668 } else { 1669 1669 // No frontend — just run the hatk server directly 1670 - const mainPath = resolve(import.meta.dirname!, 'main.ts') 1670 + const mainPath = resolve(import.meta.dirname!, 'main.js') 1671 1671 execSync(`npx tsx ${mainPath} config.yaml`, { stdio: 'inherit', cwd: process.cwd() }) 1672 1672 } 1673 1673 } catch (e: any) { ··· 1886 1886 } 1887 1887 } else if (command === 'start') { 1888 1888 try { 1889 - const mainPath = resolve(import.meta.dirname!, 'main.ts') 1889 + const mainPath = resolve(import.meta.dirname!, 'main.js') 1890 1890 execSync(`npx tsx ${mainPath} config.yaml`, { stdio: 'inherit', cwd: process.cwd() }) 1891 1891 } catch (e: any) { 1892 1892 if (e.signal === 'SIGINT' || e.signal === 'SIGTERM') process.exit(0)
+1 -1
packages/hatk/src/vite-plugin.ts
··· 65 65 }, 66 66 67 67 configureServer(server) { 68 - const mainPath = resolve(import.meta.dirname!, 'main.ts') 68 + const mainPath = resolve(import.meta.dirname!, 'main.js') 69 69 const watchDirs = ['xrpc', 'feeds', 'labels', 'jobs', 'setup', 'lexicons'].filter((d) => existsSync(d)) 70 70 const watchArgs = watchDirs.flatMap((d) => ['--watch-path', d]) 71 71 serverProcess = spawn('npx', ['tsx', 'watch', ...watchArgs, mainPath, 'config.yaml'], {
+13
packages/hatk/tsconfig.build.json
··· 1 + { 2 + "extends": "../../tsconfig.json", 3 + "compilerOptions": { 4 + "outDir": "dist", 5 + "declaration": true, 6 + "declarationMap": true, 7 + "noEmit": false, 8 + "allowImportingTsExtensions": false, 9 + "rewriteRelativeImportExtensions": true, 10 + "skipLibCheck": true 11 + }, 12 + "include": ["src"] 13 + }
+1 -1
packages/oauth-client/package.json
··· 1 1 { 2 2 "name": "@hatk/oauth-client", 3 - "version": "0.1.0", 3 + "version": "0.0.1-alpha.0", 4 4 "files": [ 5 5 "src" 6 6 ],