- slim & simple compared to chinchilla
- better suited for react apps
- functional with hopefully no memory leaks
- tested
const chipmunk = createChipmunk({
errorInterceptor: (err) => true,
headers: { 'Affiliation-Id': 'mpx' }
})
// to change config
chipmunk.updateConfig({ headers: { 'Session-Id': '345dfgsdfgw43..' } })
chipmunk.run(async (ch) => {
// requests.. e.g.
await ch.context('um.user')
// an error happens
throw new Error('foo')
}, (err) => {
// error handler is optional
console.log(err.message) // would print 'foo'
})
verbose mode
ch.updateConfig({ verbose: true })
// get context
await ch.context('um.user')
// get user, default method
await ch.action('um.user', 'get', { params: { user_id: 3 } })
// get user with associations resolved & limited attribute set
await ch.action('um.user', 'get', {
params: { user_id: 3 },
schema: `
id, first_name,
organization { name },
`
})
// get user with associations resolved & limited attribute set
// proxied through tuco (node server) -> only one request, better performance
// will throw if no schema was provided
await ch.action('um.user', 'get', {
params: { user_id: 3 },
proxy: true,
schema: `
id, first_name,
organization { name },
`
})
// create new user
await ch.action('um.user', 'create', {
body: {
first_name: 'john',
last_name: 'doe',
...rest,
}
})
// update existing user
await ch.action('um.user', 'update', {
params: { user_id: 3 },
body: {
first_name: 'johnny',
}
})
// update existing users
await ch.action('um.user', 'update', {
body: [
{ id: 3, first_name: 'johnny' },
{ id: 5, first_name: 'hermine' },
]
})
// convert to Ruby on Rails compatible 'accepts nested attributes' body
await ch.action('um.user', 'update', {
params: { user_id: 3 },
ROR: true,
body: {
first_name: 'johnny',
organization: {
name: 'walker'
}
}
})
// => converts to
// {
// first_name: 'johnny',
// organization_attributes: {
// name: 'walker'
// }
// }
// convert to 'multi' update format body (our backends support)
await ch.action('um.user', 'update', {
multi: true,
body: [
{ id: 3, first_name: 'johnny' },
{ id: 5, first_name: 'hermine' },
]
})
// converts to:
// {
// '3': { id: 3, first_name: 'johnny' },
// '5': { id: 5, first_name: 'hermine' },
// }
// return RAW results
// this does not move association references nor does it support resolving a schema
await ch.action('um.user', 'query', {
raw: true,
})
to manually resolve associations:
// fetch organizations for given users
let users = [user1, user2, user3] // ..requested earlier
user1['@associations']['organization'] // => https://url.to/organization/2'
user1.organization // => NotLoadedError!
const orgResult = await ch.fetch(users, 'organization') // => returns all associated organizations as ChipmunkResult
users = ch.assign(users, orgResult.objects, 'organization')
users[0].organization // => returns org of first user
// alternatively..
users = await ch.fetchAndAssign(users, 'organization')
users[0].organization // => returns org of first user
by default, chipmunk prefixes all cache keys with
- affiliation-id and role-id, if present
- role-id only, if present
- session-id only, if present
- 'anonymous', if none of the above
// use 'runtime' cache
ch.updateConfig({ cache: { enabled: true, engine: 'runtime' } })
// use 'storage' cache
ch.updateConfig({ cache: { enabled: true, engine: 'storage' } })
// EXAMPLE 1, write to cache for current user role
ch.updateConfig({ headers: { 'Role-Id': 5 }, cache: { enabled: true, engine: 'storage' } })
ch.cache.set('foo', 'bar')
ch.cache.get('foo') // => bar
ch.updateConfig({ headers: { 'Role-Id': 8 } })
ch.cache.get('foo') // => null
// EXAMPLE 2, write to cache, ignoring session id, role or affiliation, using runtime cache
ch.updateConfig({ headers: { 'Role-Id': 5 } })
ch.cache.set('foo', 'bar', { noPrefix: true, engine: 'runtime' })
ch.cache.get('foo', { noPrefix: true, engine: 'runtime' }) // => bar
ch.cache.get('foo', { engine: 'runtime' }) // => null
ch.updateConfig({ headers: { 'Role-Id': 8 } })
ch.cache.get('foo', { noPrefix: true, engine: 'runtime' }) // => bar
chipmunk (as chinchilla did previously) offers convenience functionality to run second level priority code after the important stuff has been processed. this allows for example to lazy load less important data after all important data has been gathered.
an example:
const notImportant = () => {
console.log('this really was not that important')
}
ch.performLater(notImportant)
const users = (await ch.action('um.user', 'query')).objects
console.log(users)
// => [user1, user2, ...]
// => this really was not that important