Object Examples
Real-world examples of working with nested objects in Pura.
User Profile
Update Basic Info
typescript
import { produceFast } from '@sylphx/pura'
interface User {
id: number
name: string
email: string
profile: {
bio: string
avatar: string
settings: {
theme: 'light' | 'dark'
notifications: boolean
}
}
}
const user: User = {
id: 1,
name: 'Alice',
email: 'alice@example.com',
profile: {
bio: 'Software engineer',
avatar: '/avatars/alice.jpg',
settings: {
theme: 'light',
notifications: true
}
}
}
// Update name
const updated = produceFast(user, $ => {
$.set(['name'], 'Alice Updated')
})
// Update nested theme
const darkMode = produceFast(user, $ => {
$.set(['profile', 'settings', 'theme'], 'dark')
})Merge Settings
typescript
import { produceFast } from '@sylphx/pura'
function updateSettings(user: User, newSettings: Partial<User['profile']['settings']>): User {
return produceFast(user, $ => {
$.merge(['profile', 'settings'], newSettings)
})
}
// Usage
const updated = updateSettings(user, {
theme: 'dark',
notifications: false
})Update Multiple Fields
typescript
import { produceFast } from '@sylphx/pura'
function updateProfile(
user: User,
updates: { name?: string; email?: string; bio?: string }
): User {
return produceFast(user, $ => {
if (updates.name) $.set(['name'], updates.name)
if (updates.email) $.set(['email'], updates.email)
if (updates.bio) $.set(['profile', 'bio'], updates.bio)
})
}
// Usage
const updated = updateProfile(user, {
name: 'Alice Smith',
bio: 'Senior Software Engineer'
})Application State
Complex State Tree
typescript
import { produceFast } from '@sylphx/pura'
interface AppState {
user: {
id: number
name: string
preferences: {
theme: string
language: string
}
}
ui: {
sidebar: {
open: boolean
width: number
}
modal: {
type: string | null
data: any
}
}
data: {
items: Array<{ id: number; title: string }>
loading: boolean
error: string | null
}
}
const initialState: AppState = {
user: {
id: 1,
name: 'Alice',
preferences: {
theme: 'light',
language: 'en'
}
},
ui: {
sidebar: {
open: true,
width: 250
},
modal: {
type: null,
data: null
}
},
data: {
items: [],
loading: false,
error: null
}
}
// Toggle sidebar
const toggleSidebar = (state: AppState): AppState => {
return produceFast(state, $ => {
$.update(['ui', 'sidebar', 'open'], open => !open)
})
}
// Show modal
const showModal = (state: AppState, type: string, data: any): AppState => {
return produceFast(state, $ => {
$.set(['ui', 'modal', 'type'], type)
$.set(['ui', 'modal', 'data'], data)
})
}
// Set loading
const setLoading = (state: AppState, loading: boolean): AppState => {
return produceFast(state, $ => {
$.set(['data', 'loading'], loading)
if (loading) {
$.set(['data', 'error'], null)
}
})
}
// Set error
const setError = (state: AppState, error: string): AppState => {
return produceFast(state, $ => {
$.set(['data', 'error'], error)
$.set(['data', 'loading'], false)
})
}Form State
Form with Validation
typescript
import { produceFast } from '@sylphx/pura'
interface FormState {
values: {
email: string
password: string
confirmPassword: string
}
errors: {
email?: string
password?: string
confirmPassword?: string
}
touched: {
email: boolean
password: boolean
confirmPassword: boolean
}
submitting: boolean
}
const initialForm: FormState = {
values: {
email: '',
password: '',
confirmPassword: ''
},
errors: {},
touched: {
email: false,
password: false,
confirmPassword: false
},
submitting: false
}
// Update field
function setField<K extends keyof FormState['values']>(
form: FormState,
field: K,
value: FormState['values'][K]
): FormState {
return produceFast(form, $ => {
$.set(['values', field], value)
$.set(['touched', field], true)
// Clear error
$.delete(['errors', field])
})
}
// Set error
function setFieldError<K extends keyof FormState['errors']>(
form: FormState,
field: K,
error: string
): FormState {
return produceFast(form, $ => {
$.set(['errors', field], error)
})
}
// Set submitting
function setSubmitting(form: FormState, submitting: boolean): FormState {
return produceFast(form, $ => {
$.set(['submitting'], submitting)
})
}Configuration
Nested Configuration
typescript
import { produceFast } from '@sylphx/pura'
interface Config {
api: {
baseUrl: string
timeout: number
retries: number
}
features: {
darkMode: boolean
analytics: boolean
beta: {
enabled: boolean
features: string[]
}
}
cache: {
enabled: boolean
ttl: number
maxSize: number
}
}
const config: Config = {
api: {
baseUrl: 'https://api.example.com',
timeout: 5000,
retries: 3
},
features: {
darkMode: false,
analytics: true,
beta: {
enabled: false,
features: []
}
},
cache: {
enabled: true,
ttl: 3600,
maxSize: 100
}
}
// Update API config
const updateApi = (config: Config, updates: Partial<Config['api']>): Config => {
return produceFast(config, $ => {
$.merge(['api'], updates)
})
}
// Enable beta feature
const enableBetaFeature = (config: Config, feature: string): Config => {
return produceFast(config, $ => {
$.set(['features', 'beta', 'enabled'], true)
const features = config.features.beta.features
if (!features.includes(feature)) {
$.set(['features', 'beta', 'features'], [...features, feature])
}
})
}Entity Management
Normalized State
typescript
import { produceFast } from '@sylphx/pura'
interface NormalizedState {
entities: {
users: Record<number, {
id: number
name: string
email: string
}>
posts: Record<number, {
id: number
title: string
authorId: number
content: string
}>
}
ids: {
users: number[]
posts: number[]
}
}
const state: NormalizedState = {
entities: {
users: {
1: { id: 1, name: 'Alice', email: 'alice@example.com' },
2: { id: 2, name: 'Bob', email: 'bob@example.com' }
},
posts: {
1: { id: 1, title: 'Post 1', authorId: 1, content: '...' },
2: { id: 2, title: 'Post 2', authorId: 2, content: '...' }
}
},
ids: {
users: [1, 2],
posts: [1, 2]
}
}
// Add user
function addUser(
state: NormalizedState,
user: { id: number; name: string; email: string }
): NormalizedState {
return produceFast(state, $ => {
$.set(['entities', 'users', user.id], user)
$.set(['ids', 'users'], [...state.ids.users, user.id])
})
}
// Update user
function updateUser(
state: NormalizedState,
userId: number,
updates: Partial<{ name: string; email: string }>
): NormalizedState {
return produceFast(state, $ => {
const user = state.entities.users[userId]
if (user) {
$.set(['entities', 'users', userId], { ...user, ...updates })
}
})
}
// Delete user
function deleteUser(state: NormalizedState, userId: number): NormalizedState {
return produceFast(state, $ => {
$.delete(['entities', 'users', userId])
$.set(['ids', 'users'], state.ids.users.filter(id => id !== userId))
})
}Deep Merging
Merge Nested Objects
typescript
import { produceFast } from '@sylphx/pura'
interface DeepObject {
level1: {
level2: {
level3: {
value: number
meta: {
updated: number
by: string
}
}
}
}
}
const obj: DeepObject = {
level1: {
level2: {
level3: {
value: 42,
meta: {
updated: Date.now(),
by: 'system'
}
}
}
}
}
// Deep update with merge
const updated = produceFast(obj, $ => {
$.merge(['level1', 'level2', 'level3', 'meta'], {
updated: Date.now(),
by: 'alice'
})
})Structural Sharing
Verify Unchanged Parts Reused
typescript
import { produceFast } from '@sylphx/pura'
const state = {
user: {
id: 1,
name: 'Alice',
profile: {
bio: 'Engineer',
settings: {
theme: 'light'
}
}
},
data: {
items: [1, 2, 3],
metadata: {
count: 3
}
}
}
// Update only theme
const next = produceFast(state, $ => {
$.set(['user', 'profile', 'settings', 'theme'], 'dark')
})
// Verify structural sharing
console.log(state.data === next.data) // true (unchanged - reused!)
console.log(state.user.id === next.user.id) // true (unchanged)
console.log(state.user.profile.bio === next.user.profile.bio) // true (unchanged)
// Only the path to 'theme' is copied
console.log(state.user.profile.settings === next.user.profile.settings) // false (changed)
console.log(state.user.profile === next.user.profile) // false (parent copied)
console.log(state.user === next.user) // false (parent copied)
console.log(state === next) // false (root copied)Performance Tips
Path-based vs Nested produce()
typescript
// ❌ Don't nest produce() calls
const bad = produce(state, draft => {
draft.user = produce(draft.user, userDraft => {
userDraft.name = 'Updated'
})
})
// ✅ Use single produceFast with path
const good = produceFast(state, $ => {
$.set(['user', 'name'], 'Updated')
})Batch Multiple Updates
typescript
// ❌ Multiple produce calls
let state = initialState
state = produceFast(state, $ => $.set(['user', 'name'], 'Alice'))
state = produceFast(state, $ => $.set(['ui', 'sidebar', 'open'], false))
// ✅ Single produce call
const next = produceFast(initialState, $ => {
$.set(['user', 'name'], 'Alice')
$.set(['ui', 'sidebar', 'open'], false)
})Next Steps
- Array Examples - Working with arrays
- Maps & Sets Examples - Collections
- Real-World Examples - Redux, React, Zustand