Skip to content

mediapeers/chipmunk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

68 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CHIPMUNK

main goals

  • slim & simple compared to chinchilla
  • better suited for react apps
  • functional with hopefully no memory leaks
  • tested

interface

setup, run blocks (always use run blocks!)

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'
})

optional configuration options

verbose mode

ch.updateConfig({ verbose: true })

contexts

// get context
await ch.context('um.user')

actions

examples

// 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' },
  ]
})

optional action options

// 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,
})

associations

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

cache

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

'perform later' jobs

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