characterforge-js 1.0.0 β†’ 1.0.1

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.
Files changed (2) hide show
  1. package/README.md +119 -339
  2. package/package.json +5 -4
package/README.md CHANGED
@@ -1,53 +1,59 @@
1
- # CharacterForge SDK
1
+ # CharacterForge JS
2
2
 
3
- AI-powered 3D character generation SDK for web and React Native applications.
3
+ TypeScript SDK for [CharacterForge](https://characterforge.app)β€”AI-powered stylized 3D character image generation for browsers, Node.js, and React Native.
4
4
 
5
- [![npm version](https://img.shields.io/npm/v/characterforge.svg)](https://www.npmjs.com/package/characterforge)
5
+ [![npm version](https://img.shields.io/npm/v/characterforge-js.svg)](https://www.npmjs.com/package/characterforge-js)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
8
  ## Features
9
9
 
10
- - 🎨 **Generate stylized 3D vinyl toy characters** using AI
11
- - ⚑ **Zero dependencies** - lightweight and fast
12
- - πŸ”„ **Built-in caching** - IndexedDB for web, file system for React Native
13
- - πŸ” **Automatic retry logic** - with exponential backoff
14
- - πŸ“± **Cross-platform** - works on web and React Native
15
- - 🎯 **TypeScript support** - fully typed for excellent IDE support
16
- - πŸ–ΌοΈ **Transparent backgrounds** - production-ready PNG images
10
+ - **Character generation** β€” Configure appearance (gender, skin, hair, clothing, eyes, accessories) and receive a PNG image URL from the CharacterForge API.
11
+ - **No runtime dependencies** β€” The package itself ships without npm dependencies; it uses `fetch` and platform APIs.
12
+ - **Client-side caching** β€” IndexedDB on web; file system + metadata storage on React Native (optional peer-style installs).
13
+ - **Retries** β€” Exponential backoff with jitter for transient failures.
14
+ - **Typed** β€” Written in TypeScript with exported types for configuration and errors.
15
+
16
+ ## Requirements
17
+
18
+ - **Node.js** β€” `>=16` per `package.json`. The client uses the global `fetch` API; use **Node 18+** (or provide a `fetch` polyfill) in Node environments.
19
+ - **Browser** β€” Modern browsers with `fetch` and IndexedDB for the default web cache.
20
+ - **React Native** β€” For native caching, install a file-system package and AsyncStorage (see below).
17
21
 
18
22
  ## Installation
19
23
 
20
24
  ```bash
21
- npm install characterforge
25
+ npm install characterforge-js
22
26
  ```
23
27
 
24
- ### React Native Additional Setup
28
+ ### React Native (caching)
25
29
 
26
- For React Native, you'll need to install one of the following file system packages:
30
+ Caching on React Native uses `expo-file-system` *or* `react-native-fs`, plus AsyncStorage for metadata. Install what matches your app:
27
31
 
28
32
  **Expo:**
33
+
29
34
  ```bash
30
35
  npx expo install expo-file-system @react-native-async-storage/async-storage
31
36
  ```
32
37
 
33
38
  **Bare React Native:**
39
+
34
40
  ```bash
35
41
  npm install react-native-fs @react-native-async-storage/async-storage
36
42
  ```
37
43
 
38
- ## Quick Start
44
+ If these are not installed, the SDK falls back to a no-op cache on unsupported environments.
45
+
46
+ ## Quick start
39
47
 
40
- ### Web / React
48
+ ### Web or Node
41
49
 
42
50
  ```typescript
43
- import { createCharacterForgeClient } from 'characterforge';
51
+ import { createCharacterForgeClient } from 'characterforge-js';
44
52
 
45
- // Create a client instance
46
53
  const client = createCharacterForgeClient({
47
- apiKey: 'your-api-key-here',
54
+ apiKey: process.env.CHARACTERFORGE_API_KEY!,
48
55
  });
49
56
 
50
- // Generate a character
51
57
  const imageUrl = await client.generate({
52
58
  gender: 'female',
53
59
  skinTone: 'medium',
@@ -60,24 +66,22 @@ const imageUrl = await client.generate({
60
66
  transparent: true,
61
67
  });
62
68
 
63
- // Use the image URL
64
- console.log('Generated image:', imageUrl);
69
+ console.log(imageUrl);
65
70
  ```
66
71
 
67
72
  ### React Native
68
73
 
69
74
  ```typescript
70
- import { createCharacterForgeClient } from 'characterforge';
71
- import { Image } from 'react-native';
75
+ import { createCharacterForgeClient } from 'characterforge-js';
76
+ import { Image, Button } from 'react-native';
77
+ import React from 'react';
72
78
 
73
- // Create a client instance
74
79
  const client = createCharacterForgeClient({
75
- apiKey: 'your-api-key-here',
80
+ apiKey: 'your-api-key',
76
81
  });
77
82
 
78
- // In your component
79
83
  function MyComponent() {
80
- const [imageUrl, setImageUrl] = React.useState(null);
84
+ const [imageUrl, setImageUrl] = React.useState<string | null>(null);
81
85
 
82
86
  const generateCharacter = async () => {
83
87
  const url = await client.generate({
@@ -97,370 +101,147 @@ function MyComponent() {
97
101
  return (
98
102
  <>
99
103
  <Button title="Generate Character" onPress={generateCharacter} />
100
- {imageUrl && <Image source={{ uri: imageUrl }} style={{ width: 300, height: 300 }} />}
104
+ {imageUrl ? <Image source={{ uri: imageUrl }} style={{ width: 300, height: 300 }} /> : null}
101
105
  </>
102
106
  );
103
107
  }
104
108
  ```
105
109
 
106
- ## API Reference
110
+ ## API
107
111
 
108
112
  ### `createCharacterForgeClient(config)`
109
113
 
110
- Creates a new SDK client instance.
114
+ Returns a `CharacterForgeClient` instance.
111
115
 
112
- **Parameters:**
116
+ **`CharacterForgeClientConfig`:**
113
117
 
114
- - `config` - Client configuration object
115
-
116
- **Configuration Options:**
117
-
118
- ```typescript
119
- interface CharacterForgeClientConfig {
120
- /** API key for authentication (required) */
121
- apiKey: string;
122
-
123
- /** Base URL for the API (optional, defaults to production) */
124
- baseUrl?: string;
125
-
126
- /** Enable/disable client-side caching (default: true) */
127
- cache?: boolean;
128
-
129
- /** Custom cache manager implementation (optional) */
130
- cacheManager?: CacheManager;
131
-
132
- /** Request timeout in milliseconds (default: 60000) */
133
- timeout?: number;
134
-
135
- /** Retry configuration (optional) */
136
- retry?: {
137
- maxRetries: number; // default: 3
138
- baseDelayMs: number; // default: 1000
139
- maxDelayMs: number; // default: 10000
140
- };
141
- }
142
- ```
143
-
144
- **Returns:** `CharacterForgeClient` instance
118
+ | Option | Description |
119
+ | --- | --- |
120
+ | `apiKey` | **Required.** API key from CharacterForge. |
121
+ | `baseUrl` | Optional. API base URL (must expose `POST .../generate-character`). Defaults to the production CharacterForge backend. |
122
+ | `cache` | Enable client cache (default: `true`). |
123
+ | `cacheManager` | Optional custom `CacheManager` implementation. |
124
+ | `timeout` | Request timeout in ms (default: `60000`). |
125
+ | `retry` | `{ maxRetries, baseDelayMs, maxDelayMs }` β€” defaults: `3`, `1000`, `10000`. |
145
126
 
146
127
  ### `client.generate(config, onStatusUpdate?)`
147
128
 
148
- Generates a character image based on the provided configuration.
149
-
150
- **Parameters:**
151
-
152
- - `config` - Character configuration object
153
- - `onStatusUpdate` (optional) - Callback function for status updates
129
+ - **`config`** β€” `CharacterConfig` (see types in the package or below).
130
+ - **`onStatusUpdate`** β€” Optional `(status: string) => void` for messages such as `"Calling AI Cloud..."`, `"Caching result..."`, `"Retrieved from Client Cache!"`.
154
131
 
155
- **Character Configuration:**
156
-
157
- ```typescript
158
- interface CharacterConfig {
159
- /** Gender: 'male' | 'female' */
160
- gender: Gender;
161
-
162
- /** Age group (optional): 'kid' | 'preteen' | 'teen' | 'young_adult' | 'adult' */
163
- ageGroup?: AgeGroupId;
164
-
165
- /** Skin tone: 'porcelain' | 'fair' | 'light' | 'medium' | 'olive' | 'brown' | 'dark' | 'deep' */
166
- skinTone: SkinToneId;
167
-
168
- /** Hair style: 'bob' | 'ponytail' | 'buns' | 'long' | 'pixie' | 'undercut' | 'quiff' | 'sidepart' | 'buzz' | 'combover' | 'messy' | 'afro' | 'curly' */
169
- hairStyle: HairStyleId;
170
-
171
- /** Hair color: 'black' | 'dark_brown' | 'brown' | 'auburn' | 'ginger' | 'dark_blonde' | 'blonde' | 'platinum' | 'grey' | 'white' | 'blue' | 'purple' */
172
- hairColor: HairColorId;
173
-
174
- /** Clothing: 'tshirt' | 'hoodie' | 'sweater' | 'jacket' | 'tank' | 'dress' | 'blouse' | 'polo' | 'buttonup' | 'henley' */
175
- clothing: ClothingItemId;
176
-
177
- /** Clothing color: 'white' | 'black' | 'navy' | 'red' | 'blue' | 'green' | 'yellow' | 'purple' | 'pink' | 'orange' | 'teal' */
178
- clothingColor: ClothingColorId;
179
-
180
- /** Eye color: 'dark' | 'brown' | 'blue' | 'green' | 'hazel' | 'grey' */
181
- eyeColor: EyeColorId;
182
-
183
- /** Accessories: array of 'none' | 'glasses' | 'sunglasses' | 'headphones' | 'cap' | 'beanie' */
184
- accessories: AccessoryId[];
185
-
186
- /** Generate with transparent background (default: true) */
187
- transparent: boolean;
188
-
189
- /** Use caching for this generation (default: true) */
190
- cache?: boolean;
191
- }
192
- ```
193
-
194
- **Returns:** `Promise<string>` - URL to the generated image
195
-
196
- **Example with status updates:**
197
-
198
- ```typescript
199
- const imageUrl = await client.generate(
200
- {
201
- gender: 'female',
202
- skinTone: 'medium',
203
- hairStyle: 'bob',
204
- hairColor: 'brown',
205
- clothing: 'hoodie',
206
- clothingColor: 'blue',
207
- eyeColor: 'brown',
208
- accessories: ['glasses'],
209
- transparent: true,
210
- },
211
- (status) => {
212
- console.log('Status:', status);
213
- // "Calling AI Cloud..."
214
- // "Caching result..."
215
- // "Retrieved from Client Cache!"
216
- }
217
- );
218
- ```
132
+ Returns `Promise<string>` β€” URL of the generated image (often a blob URL when cached on web).
219
133
 
220
134
  ### `client.clearCache()`
221
135
 
222
- Clears all cached images.
223
-
224
- **Returns:** `Promise<void>`
225
-
226
- ```typescript
227
- await client.clearCache();
228
- ```
229
-
230
- ## Error Handling
136
+ Clears the client-side cache. Returns `Promise<void>`.
231
137
 
232
- The SDK provides specific error classes for different failure scenarios:
233
-
234
- ```typescript
235
- import {
236
- AuthenticationError,
237
- InsufficientCreditsError,
238
- NetworkError,
239
- RateLimitError,
240
- GenerationError,
241
- } from 'characterforge';
242
-
243
- try {
244
- const imageUrl = await client.generate(config);
245
- } catch (error) {
246
- if (error instanceof AuthenticationError) {
247
- console.error('Invalid API key');
248
- } else if (error instanceof InsufficientCreditsError) {
249
- console.error('Not enough credits. Please purchase more.');
250
- } else if (error instanceof NetworkError) {
251
- console.error('Network error. Please check your connection.');
252
- } else if (error instanceof RateLimitError) {
253
- console.error('Rate limited. Please slow down.');
254
- } else if (error instanceof GenerationError) {
255
- console.error('Generation failed:', error.message);
256
- }
257
- }
258
- ```
259
-
260
- ## Caching
138
+ ### `client.destroy()`
261
139
 
262
- The SDK automatically caches generated images to reduce API calls and improve performance.
140
+ Releases resources (e.g. cache manager cleanup). Call when the client is no longer needed.
263
141
 
264
- ### Web Caching
142
+ ### `VERSION`
265
143
 
266
- - Uses **IndexedDB** for persistent storage
267
- - Automatically manages object URLs to prevent memory leaks
268
- - Configurable cache size (default: 100 images)
269
- - Auto-expires after 7 days
270
- - Automatically cleans up old entries
144
+ The package exports `VERSION` (string) matching the published SDK version.
271
145
 
272
- ### React Native Caching
146
+ ## `CharacterConfig` (summary)
273
147
 
274
- - Uses **file system** for image storage
275
- - Uses **AsyncStorage** for metadata
276
- - Platform-specific implementations for Expo and bare React Native
277
- - Same cache size and expiry settings as web
148
+ | Field | Notes |
149
+ | --- | --- |
150
+ | `gender` | `'male' \| 'female'` |
151
+ | `ageGroup` | Optional: `'kid' \| 'preteen' \| 'teen' \| 'young_adult' \| 'adult'` |
152
+ | `skinTone` | e.g. `'porcelain'` … `'deep'` (see `SkinToneId` in types) |
153
+ | `hairStyle` | e.g. `'bob'`, `'quiff'`, `'afro'`, … (`HairStyleId`) |
154
+ | `hairColor` | (`HairColorId`) |
155
+ | `clothing` | (`ClothingItemId`) |
156
+ | `clothingColor` | (`ClothingColorId`) |
157
+ | `eyeColor` | (`EyeColorId`) |
158
+ | `accessories` | `AccessoryId[]` β€” e.g. `'none'`, `'glasses'`, `'cap'` |
159
+ | `transparent` | Whether the image uses a transparent background |
160
+ | `cache` | Optional per-request override for caching |
278
161
 
279
- ### Disabling Cache
280
-
281
- You can disable caching globally or per-request:
162
+ Import the full unions from `characterforge-js`:
282
163
 
283
164
  ```typescript
284
- // Disable globally
285
- const client = createCharacterForgeClient({
286
- apiKey: 'your-api-key',
287
- cache: false,
288
- });
289
-
290
- // Disable per-request
291
- const imageUrl = await client.generate({
292
- ...config,
293
- cache: false,
294
- });
165
+ import type {
166
+ CharacterConfig,
167
+ CharacterForgeClientConfig,
168
+ Gender,
169
+ SkinToneId,
170
+ HairStyleId,
171
+ } from 'characterforge-js';
295
172
  ```
296
173
 
297
- ### Custom Cache Manager
298
-
299
- For advanced use cases, you can provide a custom cache implementation:
300
-
301
- ```typescript
302
- import { CacheManager } from 'characterforge';
303
-
304
- class MyCustomCache implements CacheManager {
305
- async get(key: string): Promise<string | null> {
306
- // Your implementation
307
- }
174
+ ## Errors
308
175
 
309
- async set(key: string, data: Blob | string): Promise<string> {
310
- // Your implementation
311
- }
176
+ The SDK throws typed errors. Common API-related classes (also re-exported from the main entry):
312
177
 
313
- async clear(): Promise<void> {
314
- // Your implementation
315
- }
316
- }
317
-
318
- const client = createCharacterForgeClient({
319
- apiKey: 'your-api-key',
320
- cacheManager: new MyCustomCache(),
321
- });
322
- ```
178
+ - `AuthenticationError` β€” Invalid or missing API key.
179
+ - `InsufficientCreditsError` β€” Not enough credits.
180
+ - `RateLimitError` β€” HTTP 429 / too many requests.
181
+ - `NetworkError` β€” Timeouts and network failures.
182
+ - `ApiError` β€” Other API HTTP errors that participate in retries.
183
+ - `GenerationError` β€” Generation or response parsing failures.
323
184
 
324
- ## Advanced Configuration
185
+ `CharacterForgeError` is an **alias** for `GenerationError` (exported from the client module for backward compatibility).
325
186
 
326
- ### Custom Base URL
327
-
328
- If you're self-hosting or using a custom endpoint:
187
+ Additional utilities and types live under the same package:
329
188
 
330
189
  ```typescript
331
- const client = createCharacterForgeClient({
332
- apiKey: 'your-api-key',
333
- baseUrl: 'https://your-custom-domain.com/functions/v1',
334
- });
190
+ import {
191
+ AppError,
192
+ AuthorizationError,
193
+ ImageProcessingError,
194
+ ValidationError,
195
+ ConfigValidationError,
196
+ CacheError,
197
+ PaymentError,
198
+ isAppError,
199
+ isAuthenticationError,
200
+ isInsufficientCreditsError,
201
+ isNetworkError,
202
+ isRateLimitError,
203
+ parseError,
204
+ getUserFriendlyMessage,
205
+ } from 'characterforge-js';
335
206
  ```
336
207
 
337
- ### Custom Timeout
208
+ ## Caching
338
209
 
339
- Adjust the request timeout (default is 60 seconds):
210
+ - **Web** β€” `WebCacheManager` uses IndexedDB, caps entries (e.g. 100), and expires old data (e.g. 7 days). Object URLs are managed to reduce leaks.
211
+ - **React Native** β€” `NativeCacheManager` stores files under a cache directory and keeps metadata in AsyncStorage.
212
+ - **Override** β€” Pass `cache: false` in client config or per `generate()` call. Implement `CacheManager` for custom storage.
340
213
 
341
- ```typescript
342
- const client = createCharacterForgeClient({
343
- apiKey: 'your-api-key',
344
- timeout: 30000, // 30 seconds
345
- });
346
- ```
214
+ Advanced exports: `createCacheManager`, `WebCacheManager`, `NativeCacheManager`, `isBrowser`, `isReactNative`.
347
215
 
348
- ### Custom Retry Configuration
216
+ ## Advanced configuration
349
217
 
350
- Adjust the retry behavior:
218
+ **Custom base URL** (self-hosted or staging):
351
219
 
352
220
  ```typescript
353
221
  const client = createCharacterForgeClient({
354
222
  apiKey: 'your-api-key',
355
- retry: {
356
- maxRetries: 5,
357
- baseDelayMs: 2000,
358
- maxDelayMs: 20000,
359
- },
223
+ baseUrl: 'https://your-deployment.example.com/functions/v1',
360
224
  });
361
225
  ```
362
226
 
363
- ## TypeScript Support
364
-
365
- The SDK is written in TypeScript and provides full type definitions:
366
-
367
- ```typescript
368
- import type {
369
- CharacterConfig,
370
- CharacterForgeClientConfig,
371
- Gender,
372
- SkinToneId,
373
- HairStyleId,
374
- // ... and more
375
- } from 'characterforge';
376
- ```
377
-
378
- All types are exported for your convenience, enabling excellent IDE autocomplete and type checking.
227
+ The client calls `POST ${baseUrl}/generate-character`.
379
228
 
380
- ## Examples
229
+ **Timeout and retries** β€” Set `timeout` and `retry` on the client config as needed.
381
230
 
382
- ### Complete React Component
231
+ ## Logging
383
232
 
384
- ```tsx
385
- import React, { useState } from 'react';
386
- import { createCharacterForgeClient } from 'characterforge';
233
+ For debugging integrations, the package exports `Logger`, `logger`, `sdkLogger`, and types `LogLevel`, `LogEntry`, `LoggerConfig`.
387
234
 
388
- const client = createCharacterForgeClient({
389
- apiKey: process.env.REACT_APP_CHARACTER_FORGE_KEY!,
390
- });
235
+ ## API key
391
236
 
392
- export function CharacterGenerator() {
393
- const [imageUrl, setImageUrl] = useState<string | null>(null);
394
- const [loading, setLoading] = useState(false);
395
- const [status, setStatus] = useState('');
396
- const [error, setError] = useState<string | null>(null);
397
-
398
- const handleGenerate = async () => {
399
- setLoading(true);
400
- setError(null);
401
-
402
- try {
403
- const url = await client.generate(
404
- {
405
- gender: 'female',
406
- skinTone: 'medium',
407
- hairStyle: 'bob',
408
- hairColor: 'brown',
409
- clothing: 'hoodie',
410
- clothingColor: 'blue',
411
- eyeColor: 'brown',
412
- accessories: ['glasses'],
413
- transparent: true,
414
- },
415
- (status) => setStatus(status)
416
- );
417
-
418
- setImageUrl(url);
419
- } catch (err) {
420
- setError(err instanceof Error ? err.message : 'Generation failed');
421
- } finally {
422
- setLoading(false);
423
- }
424
- };
425
-
426
- return (
427
- <div>
428
- <button onClick={handleGenerate} disabled={loading}>
429
- {loading ? 'Generating...' : 'Generate Character'}
430
- </button>
431
-
432
- {status && <p>Status: {status}</p>}
433
- {error && <p style={{ color: 'red' }}>Error: {error}</p>}
434
-
435
- {imageUrl && (
436
- <img
437
- src={imageUrl}
438
- alt="Generated character"
439
- style={{ width: 300, height: 300 }}
440
- />
441
- )}
442
- </div>
443
- );
444
- }
445
- ```
237
+ 1. Open [characterforge.app](https://characterforge.app) and sign in.
238
+ 2. Use the developer/dashboard area to create an API key.
239
+ 3. Keep keys out of source control; use environment variables or your host’s secret storage.
446
240
 
447
- ## Getting an API Key
241
+ ## Repository and issues
448
242
 
449
- 1. Visit [characterforge.app](https://characterforge.app)
450
- 2. Sign up for an account
451
- 3. Navigate to the Developer Dashboard
452
- 4. Create a new API key
453
- 5. Copy your API key and use it in your application
454
-
455
- **Important:** Keep your API key secret and never commit it to version control. Use environment variables or secure key management systems.
456
-
457
- ## Support
458
-
459
- - πŸ“§ Email: support@characterforge.app
460
- - πŸ› Issues: [GitHub Issues](https://github.com/characterforge/sdk/issues)
461
- - πŸ“– Documentation: [characterforge.app/docs](https://characterforge.app/docs)
462
-
463
- **Note:** This package is published as `characterforge` on npm.
243
+ - **Repository:** [github.com/inceptivco/ToyForge](https://github.com/inceptivco/ToyForge) (this SDK lives under the `sdk` directory in that monorepo).
244
+ - **Issues:** [github.com/inceptivco/ToyForge/issues](https://github.com/inceptivco/ToyForge/issues)
464
245
 
465
246
  ## License
466
247
 
@@ -468,5 +249,4 @@ MIT Β© CharacterForge
468
249
 
469
250
  ## Contributing
470
251
 
471
- Contributions are welcome! Please feel free to submit a Pull Request.
472
-
252
+ Contributions are welcome via pull requests against the repository above.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "characterforge-js",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "AI-powered 3D character generation SDK for web and React Native",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -39,13 +39,15 @@
39
39
  "license": "MIT",
40
40
  "repository": {
41
41
  "type": "git",
42
- "url": "https://github.com/characterforge/sdk"
42
+ "url": "git+https://github.com/inceptivco/ToyForge.git",
43
+ "directory": "sdk"
43
44
  },
44
45
  "bugs": {
45
- "url": "https://github.com/characterforge/sdk/issues"
46
+ "url": "https://github.com/inceptivco/ToyForge/issues"
46
47
  },
47
48
  "homepage": "https://characterforge.app",
48
49
  "devDependencies": {
50
+ "@types/node": "^25.5.2",
49
51
  "tsup": "^8.0.0",
50
52
  "typescript": "^5.3.0"
51
53
  },
@@ -56,4 +58,3 @@
56
58
  "access": "public"
57
59
  }
58
60
  }
59
-