howone 0.1.11 → 0.1.12

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.
@@ -1,215 +0,0 @@
1
- # HowOne SDK Usage Patterns
2
-
3
- This file covers what the type declarations don't: generation recipes, usage examples, and known traps. For the complete public API (all types, method signatures, exports), read `node_modules/@howone/sdk/dist/index.d.ts` and `node_modules/@howone/sdk/dist/react.d.ts` first.
4
-
5
- ## SDK Mental Model
6
-
7
- - `createClient(...)` creates the base HowOne client with auth, entity, AI, upload, and user helpers.
8
- - `client.entity<TRecord, TCreate, TUpdate>('EntityName')` creates one typed entity client.
9
- - `defineEntities(...)` plus `withEntities(client, entities)` makes `howone.entities.<EntityName>` typed in app code.
10
- - `defineAiAction(...)` plus `defineAiActions(...)` plus `withAiActions(...)` makes `howone.ai.<actionName>.run|stream|events` typed in app code.
11
- - `@howone/sdk/react` provides auth/theme/loading UI primitives only. It does not provide entity, query, or AI data hooks.
12
- - `.howone/database/manifest.json` and `.howone/ai/manifest.json` are the generated contracts. App source should be generated from those manifests, not from memory.
13
-
14
- ## App SDK Entry
15
-
16
- Preferred Vite app entry shape:
17
-
18
- ```ts
19
- import {
20
- createClient,
21
- defineAiAction,
22
- defineAiActions,
23
- defineEntities,
24
- type EntityRecord,
25
- withAiActions,
26
- withEntities,
27
- } from '@howone/sdk'
28
- import { z } from 'zod'
29
-
30
- const client = createClient({
31
- projectId: import.meta.env.VITE_HOWONE_PROJECT_ID,
32
- env: import.meta.env.VITE_HOWONE_ENV,
33
- })
34
-
35
- export const entities = defineEntities({
36
- // Todo: client.entity<Todo, TodoCreate, TodoUpdate>('Todo'),
37
- })
38
-
39
- export const ai = defineAiActions({
40
- // generateImage: defineAiAction('generateImage', {
41
- // inputSchema: generateImageInputSchema,
42
- // }),
43
- })
44
-
45
- const howone = withAiActions(withEntities(client, entities), ai)
46
-
47
- export default howone
48
- ```
49
-
50
- ## Manifest-To-Code Recipe
51
-
52
- When backend metadata has been synced, generate app SDK code in this order:
53
-
54
- 1. Read `src/lib/sdk.ts` to preserve the template's import style and existing bindings.
55
- 2. Read `.howone/database/manifest.json` for entity names and fields. Generate `Record`, `Create`, and `Update` types, then bind each entity with `client.entity<Record, Create, Update>('EntityName')`.
56
- 3. Read `.howone/ai/manifest.json` for AI capability names and JSON schemas. Generate zod input schemas and, only when safe, output schemas.
57
- 4. Export a single default `howone` client built by composing `withEntities` and `withAiActions`.
58
- 5. In UI code, import the default client and call `howone.entities.<Entity>.*` or `howone.ai.<action>.run(...)`.
59
-
60
- Basic JSON schema mapping for generated zod:
61
-
62
- ```ts
63
- string -> z.string()
64
- number -> z.number()
65
- integer -> z.number().int()
66
- boolean -> z.boolean()
67
- array -> z.array(...)
68
- object -> z.object({ ... })
69
- enum -> z.enum([...])
70
- missing from required[] -> .optional()
71
- ```
72
-
73
- ## Entity Types
74
-
75
- Prefer explicit payload types:
76
-
77
- ```ts
78
- export type StoryRecord = EntityRecord & {
79
- title: string
80
- content: string
81
- prompt: string
82
- }
83
-
84
- export type StoryCreate = {
85
- title: string
86
- content: string
87
- prompt: string
88
- }
89
-
90
- export type StoryUpdate = Partial<StoryCreate>
91
-
92
- export const entities = defineEntities({
93
- Story: client.entity<StoryRecord, StoryCreate, StoryUpdate>('Story'),
94
- })
95
- ```
96
-
97
- Generated entity app code usually needs only these calls:
98
-
99
- ```ts
100
- const result = await howone.entities.Story.query({
101
- search,
102
- page: { number: 1, size: 20 },
103
- orderBy: { createdDate: 'desc' },
104
- })
105
-
106
- await howone.entities.Story.create({ title, content, prompt })
107
- await howone.entities.Story.update(id, { title })
108
- await howone.entities.Story.delete(id)
109
- ```
110
-
111
- Prefer `query()` for list UIs that need paging/search/sort metadata. Use `list()` only for simple array reads.
112
-
113
- Avoid this for generated create payloads:
114
-
115
- ```ts
116
- type StoryCreate = Omit<StoryRecord, 'id' | 'createdDate' | 'updatedDate'>
117
- ```
118
-
119
- `EntityRecord` has an index signature, so `Omit` can make generated create types looser than intended.
120
-
121
- ## AI Action Types
122
-
123
- Generate zod schemas from `.howone/ai/manifest.json`:
124
-
125
- ```ts
126
- export const generateStoryInputSchema = z.object({
127
- topic: z.string().min(1),
128
- ageRange: z.enum(['3-5', '6-8', '9-12']),
129
- })
130
-
131
- export const generateStoryOutputSchema = z.object({
132
- title: z.string(),
133
- content: z.string(),
134
- })
135
-
136
- export type GenerateStoryInput = z.infer<typeof generateStoryInputSchema>
137
- export type GenerateStoryOutput = z.infer<typeof generateStoryOutputSchema>
138
-
139
- export const ai = defineAiActions({
140
- generateStory: defineAiAction('generateStory', {
141
- inputSchema: generateStoryInputSchema,
142
- mode: 'run',
143
- }),
144
- })
145
- ```
146
-
147
- Call from app code:
148
-
149
- ```ts
150
- const result = await howone.ai.generateStory.run({
151
- topic,
152
- ageRange,
153
- })
154
- const story = result.finalResult as GenerateStoryOutput
155
- ```
156
-
157
- For streaming:
158
-
159
- ```ts
160
- const session = howone.ai.generateStory.stream(input)
161
- session.cancel()
162
- ```
163
-
164
- For event iteration:
165
-
166
- ```ts
167
- for await (const event of howone.ai.generateStory.events(input)) {
168
- console.log(event)
169
- }
170
- ```
171
-
172
- ## AI Output Validation
173
-
174
- `run()` validates input with `inputSchema`, calls the workflow, then validates the **raw `ExecutionResult`** (the full SSE envelope) with `outputSchema`. It does **not** automatically unwrap `result.finalResult`.
175
-
176
- If you want to type the final result only, omit `outputSchema` and unwrap manually:
177
-
178
- ```ts
179
- const result = await howone.ai.generateStory.run(input) // returns AiResult
180
- const finalResult = result.finalResult as GenerateStoryOutput
181
- ```
182
-
183
- Only define `outputSchema` when it matches the full `ExecutionResult` envelope or after verifying the SDK has changed to validate `finalResult` directly.
184
-
185
- ## AI Result Persistence
186
-
187
- For AI-generated data that should be saved:
188
-
189
- 1. Define AI input/output schemas from `.howone/ai/manifest.json`.
190
- 2. Define entity fields from the AI output schema.
191
- 3. Add only needed request metadata fields, such as prompt, selected options, language, status, or timestamps.
192
- 4. Save with `howone.entities.<Entity>.create(...)`.
193
-
194
- Example:
195
-
196
- ```ts
197
- const story = await howone.ai.generateStory.run(input)
198
- const finalResult = story.finalResult as GenerateStoryOutput
199
-
200
- await howone.entities.Story.create({
201
- title: finalResult.title,
202
- content: finalResult.content,
203
- prompt: input.topic,
204
- })
205
- ```
206
-
207
- ## Generated Code Checklist
208
-
209
- - `src/lib/sdk.ts` imports only APIs it uses.
210
- - `createClient` uses `import.meta.env.VITE_HOWONE_PROJECT_ID` and `import.meta.env.VITE_HOWONE_ENV`.
211
- - Entity names match `.howone/database/manifest.json`.
212
- - AI action names and schemas match `.howone/ai/manifest.json`.
213
- - zod schemas are strict enough for generated UI inputs and backend contracts.
214
- - UI code calls `howone.ai.<action>.run(input)` and `howone.entities.<Entity>.*`.
215
- - No generated source file is written under `.howone`.