ugly-app 0.1.42 → 0.1.43

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 CHANGED
@@ -6,9 +6,9 @@ A full-stack TypeScript framework for building production-ready web applications
6
6
 
7
7
  - **Server**: Express + WebSocket with type-safe RPC and Zod validation
8
8
  - **Client**: React + Vite with typed routing, lazy pages, and popup management
9
- - **Database**: MongoDB with typed collections, indexes, migrations, and live document tracking
9
+ - **Database**: MongoDB with typed collections, dot-notation updates, indexes, migrations, and live document tracking
10
10
  - **Auth**: JWT + HttpOnly cookies, ugly.bot OAuth out of the box, extensible via `AuthProvider`
11
- - **AI**: Text generation (Together, Claude, OpenAI, Google, Groq, Fireworks) + image generation (Together, FAL, Google, Wavespeed)
11
+ - **AI**: Text generation (Together, Claude, OpenAI, Google, Groq, Fireworks) + image generation (Together, FAL, Google, Wavespeed) + embeddings + STT/TTS
12
12
  - **Storage**: Cloudflare R2 / AWS S3 with presigned uploads
13
13
  - **CLI**: `ugly-app` commands for dev, build, deploy, migrations, logs, and auth utilities
14
14
 
@@ -143,7 +143,7 @@ export const requests = defineRequests({
143
143
 
144
144
  - `fn({ input, output })` — defines a mutation (write operation). `input` and `output` are Zod schemas.
145
145
  - `req({ input, output })` — defines a query (read operation).
146
- - `defineFunctions()` / `defineRequests()` — identity wrappers that preserve types.
146
+ - `defineFunctions()` / `defineRequests()` — identity wrappers that preserve types. `defineCalls` is an alias for `defineFunctions`.
147
147
  - `z` is re-exported from Zod for convenience.
148
148
 
149
149
  ### Collections (`shared/collections.ts`)
@@ -164,11 +164,14 @@ export const collections = defineCollections({
164
164
  });
165
165
  ```
166
166
 
167
- Collection meta fields:
168
- - `cache` — enable in-memory caching
169
- - `trackable` — allow real-time `trackDoc`/`trackDocs` subscriptions
170
- - `public` — accessible without auth
171
- - `parent` — parent collection name for cascade deletes (or `null`)
167
+ Each collection definition has:
168
+ - `type` — phantom field for TypeScript type inference (never read at runtime)
169
+ - `meta` — runtime metadata:
170
+ - `cache` — enable in-memory caching
171
+ - `trackable` — allow real-time `trackDoc`/`trackDocs` subscriptions
172
+ - `public` — accessible without auth
173
+ - `parent` — parent collection name for cascade deletes (or `null`)
174
+ - `onDelete?` — optional callback invoked on document deletion
172
175
 
173
176
  All documents extend `DBObject`: `{ id: string, version: number, created: Date, updated: Date }`.
174
177
 
@@ -282,6 +285,10 @@ Wraps your app with context for `useApp()`. Provides user info, socket access, p
282
285
  | `splashDone(step)` | Mark a splash screen step as complete |
283
286
  | `localizer(key, params?)` | Localize a string key |
284
287
 
288
+ `useAppOptional()` returns the same context or `null` if outside `<AppProvider>`.
289
+
290
+ `useLocalizer()` returns the localizer function (falls back to identity if outside provider).
291
+
285
292
  ### Router
286
293
 
287
294
  #### Setup (`client/router.ts`)
@@ -315,7 +322,18 @@ export const allPages = {
315
322
  ```
316
323
 
317
324
  - **`lazyPage(factory)`** — lazy-imports a default-exported React component. The component receives route params as props.
318
- - **`lazyPageLoader(factory)`** — lazy-imports an async loader function `(params) => Promise<ReactElement>` for routes that need data fetching before render. The loader file is the chunk boundary.
325
+ - **`lazyPageLoader(factory)`** — lazy-imports an async loader function `(params) => Promise<ReactElement>` for routes that need data fetching before render. The loader file is the chunk boundary — it can statically import its page component.
326
+
327
+ **`lazyPageLoader` example:**
328
+
329
+ ```typescript
330
+ // pages/SlowPageLoader.tsx
331
+ import SlowPage from './SlowPage'; // static import OK — same chunk
332
+ export default async function PageLoader({ id }: { id: string }) {
333
+ const data = await fetchSlowData(id);
334
+ return <SlowPage {...data} />;
335
+ }
336
+ ```
319
337
 
320
338
  #### Navigation with `useRouter()`
321
339
 
@@ -354,10 +372,12 @@ handle.hide(); // dismiss programmatically
354
372
  ```
355
373
 
356
374
  Popup modes:
357
- - **`block`** — dark backdrop (40% opacity), clicking backdrop does NOT dismiss
375
+ - **`block`** (default) — dark backdrop (40% opacity), clicking backdrop does NOT dismiss
358
376
  - **`transient`** — light backdrop (20% opacity), clicking backdrop dismisses
359
377
  - **`contextMenu`** — same as transient, intended for menus and pickers
360
378
 
379
+ `renderLayer` receives `{ content, spring, hide }` — `spring` is an animated value from 0 to 1, `hide` is a function to close the popup.
380
+
361
381
  #### `Link` component
362
382
 
363
383
  ```tsx
@@ -423,7 +443,7 @@ configurator.setAuth({
423
443
  await ctx.db.setDoc(collections.note, doc);
424
444
  await ctx.db.setDoc(collections.note, doc, { skipIfExists: true });
425
445
 
426
- // Partial update — only specified fields
446
+ // Partial update — only specified fields (supports dot-notation paths)
427
447
  await ctx.db.setDocFields(collections.note, id, { title: 'New title' });
428
448
 
429
449
  // Partial update — returns null if document doesn't exist (no error)
@@ -447,6 +467,10 @@ const notes = await ctx.db.getDocs(collections.note, { userId }, { sort: { creat
447
467
  const results = await ctx.db.getQuery<MyResult>('note', pipeline, { skip, limit });
448
468
  const count = await ctx.db.getQueryCount('note', pipeline);
449
469
  const raw = await ctx.db.getQueryRaw<T>('note', pipeline);
470
+
471
+ // Dynamic/untyped access (when collection name is a runtime string)
472
+ const doc = await ctx.db.rawGetDoc(collectionName, id);
473
+ const docs = await ctx.db.rawGetDocs(collectionName, filter);
450
474
  ```
451
475
 
452
476
  ### Deleting
@@ -474,7 +498,7 @@ import { dbDefaults } from 'ugly-app/shared';
474
498
  // dbDefaults() returns { version: 1, created: new Date(), updated: new Date() }
475
499
  const doc = { id: newId(), ...dbDefaults(), title: 'Hello' };
476
500
 
477
- // createUserHelper — typed user CRUD
501
+ // createUserHelper — typed user CRUD with get, set, update methods
478
502
  const userHelper = createUserHelper<User>(collections.user);
479
503
  const user = await userHelper.get(db, userId);
480
504
  await userHelper.set(db, { id: userId, ...dbDefaults(), email });
@@ -494,6 +518,8 @@ export const dbIndexes = defineDbIndexes({
494
518
  });
495
519
  ```
496
520
 
521
+ Index types supported: standard (`IndexDef`), text search (`SearchIndexDef`), and vector/embedding (`VectorIndexDef` with cosine, euclidean, or dotProduct similarity).
522
+
497
523
  Run `npm run db:init` to create/update indexes.
498
524
 
499
525
  ---
@@ -547,13 +573,33 @@ import { createImageGenClient } from 'ugly-app';
547
573
  const imageGen = createImageGenClient();
548
574
  ```
549
575
 
576
+ ### Embeddings
577
+
578
+ ```typescript
579
+ import { createEmbeddingClient, cosineSimilarity } from 'ugly-app';
580
+ const embeddings = createEmbeddingClient();
581
+ const similarity = cosineSimilarity(vectorA, vectorB);
582
+ ```
583
+
584
+ ### Speech-to-text / Text-to-speech
585
+
586
+ ```typescript
587
+ // Server-side providers
588
+ import { registerSTTProvider, groqWhisperSTTProvider, loadVADModel } from 'ugly-app';
589
+ import { registerTTSProvider, azureTTSProvider } from 'ugly-app';
590
+
591
+ // Client-side hooks
592
+ import { useSTT, useTTS, AudioPlayer, AudioRecorder } from 'ugly-app/client';
593
+ ```
594
+
550
595
  ### Custom providers
551
596
 
552
597
  ```typescript
553
- import { registerTextGenProvider, registerImageGenProvider } from 'ugly-app';
598
+ import { registerTextGenProvider, registerImageGenProvider, registerEmbeddingProvider } from 'ugly-app';
554
599
 
555
600
  registerTextGenProvider('myProvider', myTextGenImplementation);
556
601
  registerImageGenProvider('myProvider', myImageGenImplementation);
602
+ registerEmbeddingProvider('myProvider', myEmbeddingImplementation);
557
603
  ```
558
604
 
559
605
  ### Client-side AI calls
@@ -588,7 +634,7 @@ const url = storage.url('public', destKey);
588
634
  const { uploadUrl, resultUrl } = await storage.presignedPut('temp', key);
589
635
  ```
590
636
 
591
- Buckets: `'public'` and `'temp'`.
637
+ Buckets: `'public'` and `'temp'`. Supports Cloudflare R2 (production) or MinIO (dev).
592
638
 
593
639
  Static build-time assets go in `client/public/`. Never hardcode `/asset/...` paths — use the `buildId` from `shared/Build.ts`.
594
640
 
@@ -626,7 +672,7 @@ sub(); // unsubscribe
626
672
  ### Redis
627
673
 
628
674
  ```typescript
629
- import { getRedisClient } from 'ugly-app';
675
+ import { getRedisClient, redisGet, redisSet, redisDel, redisPublish, redisSubscribe } from 'ugly-app';
630
676
  const redis = getRedisClient();
631
677
  ```
632
678
 
@@ -641,6 +687,15 @@ configurator.setWorkerQueue(queue);
641
687
  await enqueueTask('taskName', payload);
642
688
  ```
643
689
 
690
+ ### Billing
691
+
692
+ ```typescript
693
+ import { initBillingGateway, getBillingGateway } from 'ugly-app';
694
+
695
+ await initBillingGateway({ /* config */ });
696
+ const billing = getBillingGateway();
697
+ ```
698
+
644
699
  ### Client error capture
645
700
 
646
701
  ```typescript
@@ -672,21 +727,20 @@ Server-side, `getFeedbackHandlers(maintainBotUserId)` provides the RPC handlers
672
727
  await ctx.rateLimit.check();
673
728
  ```
674
729
 
675
- ### Embeddings
676
-
677
- ```typescript
678
- import { createEmbeddingClient, registerEmbeddingProvider } from 'ugly-app';
679
- const embeddings = createEmbeddingClient();
680
- ```
681
-
682
- ### Billing
730
+ ---
683
731
 
684
- ```typescript
685
- import { initBillingGateway, getBillingGateway } from 'ugly-app';
732
+ ## Built-in endpoints
686
733
 
687
- await initBillingGateway({ /* config */ });
688
- const billing = getBillingGateway();
689
- ```
734
+ | Endpoint | Description |
735
+ |----------|-------------|
736
+ | `GET /health` | Health check — returns `{ status: 'ok', timestamp }` |
737
+ | `POST /auth/verify` | Exchange OAuth code for a session cookie |
738
+ | `POST /auth/logout` | Clear the auth cookie |
739
+ | `GET /auth/token` | Refresh and return the current token |
740
+ | `GET /auth/url` | Get the OAuth popup URL |
741
+ | `POST /ai/request` | AI proxy — forwards to ugly.bot (requires auth) |
742
+ | `POST /api/client-error` | Client-side error capture |
743
+ | `GET /my_feedback` | User feedback history (markdown, requires auth) |
690
744
 
691
745
  ---
692
746
 
@@ -734,6 +788,7 @@ Run with `npm run db:migrate`. Use `npm run db:migrate -- --status` to preview p
734
788
  | Variable | Description |
735
789
  |----------|-------------|
736
790
  | `JWT_SECRET` | **Required** — signs auth tokens |
791
+ | `JWT_EXPIRY_SECONDS` | Token lifetime (optional) |
737
792
  | `MONGODB_URI` | MongoDB connection string |
738
793
  | `PORT` | Server port (default: 3000) |
739
794
  | `NODE_ENV` | `development` or `production` |
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/cli/scaffold.ts"],"names":[],"mappings":"AA8DA,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DxE"}
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/cli/scaffold.ts"],"names":[],"mappings":"AAyFA,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4DxE"}
@@ -38,7 +38,33 @@ function generateEnv(examplePath, projectName) {
38
38
  })
39
39
  .join('\n');
40
40
  }
41
+ /** Locate the `code` binary — checks PATH then known macOS app bundle locations. */
42
+ function findCodeCli() {
43
+ try {
44
+ execSync('code --version', { stdio: 'ignore' });
45
+ return 'code';
46
+ }
47
+ catch { /* not in PATH */ }
48
+ const candidates = process.platform === 'win32'
49
+ ? [
50
+ path.join(process.env['LOCALAPPDATA'] ?? '', 'Programs\\Microsoft VS Code\\bin\\code.cmd'),
51
+ path.join(process.env['ProgramFiles'] ?? '', 'Microsoft VS Code\\bin\\code.cmd'),
52
+ path.join(process.env['ProgramFiles(x86)'] ?? '', 'Microsoft VS Code\\bin\\code.cmd'),
53
+ ]
54
+ : [
55
+ '/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code',
56
+ path.join(os.homedir(), 'Applications/Visual Studio Code.app/Contents/Resources/app/bin/code'),
57
+ ];
58
+ for (const p of candidates) {
59
+ if (fs.existsSync(p))
60
+ return `"${p}"`;
61
+ }
62
+ return null;
63
+ }
41
64
  async function installVsixExtension() {
65
+ const codeCli = findCodeCli();
66
+ if (!codeCli)
67
+ return; // VSCode not found — skip silently
42
68
  const url = 'https://ugly.bot/asset/ugly-bot.vsix';
43
69
  const vsixPath = path.join(os.tmpdir(), 'ugly-bot.vsix');
44
70
  try {
@@ -48,7 +74,7 @@ async function installVsixExtension() {
48
74
  throw new Error(`HTTP ${res.status}`);
49
75
  const buf = await res.arrayBuffer();
50
76
  await fs.writeFile(vsixPath, Buffer.from(buf));
51
- execSync(`code --install-extension "${vsixPath}"`, { stdio: 'inherit' });
77
+ execSync(`${codeCli} --install-extension "${vsixPath}"`, { stdio: 'inherit' });
52
78
  console.log('[ugly-app] VSCode extension installed.');
53
79
  }
54
80
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/cli/scaffold.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/cli/scaffold.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ugly-app",
3
- "version": "0.1.42",
3
+ "version": "0.1.43",
4
4
  "type": "module",
5
5
  "main": "./dist/server/index.js",
6
6
  "exports": {
@@ -11,7 +11,7 @@ import type { ImageGenModel, TextGenModel } from 'ugly-app/shared';
11
11
  import { imageGenModels, textGenModels } from 'ugly-app/shared';
12
12
 
13
13
  type Mode = 'text' | 'image';
14
- type LogEntry = { ts: number; msg: string; kind: 'info' | 'ok' | 'err' };
14
+ interface LogEntry { ts: number; msg: string; kind: 'info' | 'ok' | 'err' }
15
15
 
16
16
  function fmt(ms: number): string {
17
17
  return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`;