property: 'session',
store: new Map(),
getSessionKey: (ctx) => ctx.from && ctx.chat && `${ctx.from.id}:${ctx.chat.id}`,
...opts
}
const ttlMs = options.ttl && options.ttl * 1000
const defaults = new Map() // для синхронизации значений по умолчанию в течении одноко тика
return (ctx, next) => {
const key = options.getSessionKey(ctx)
if (!key) {
return next(ctx)
}
const now = Date.now()
return Promise.resolve(options.store.get(key))
.then((state) => {
if (!state || state.expires < now) {
state = defaults.get(key)
if (!state) {
state = { session: {} }
defaults.set(key, state)
setImmediate(() => defaults.clear(key)) // отчищаем после тика, дальше уже в штатном режиме
}
}
return state
})
.then(({ session }) => {
Object.defineProperty(ctx, options.property, {
get: function () { return session },
set: function (newValue) { Object.assign(session, newValue) }
})
return next(ctx).then(() => options.store.set(key, {
session,
expires: ttlMs ? now + ttlMs : Infinity
}))
})
}
}
Обсуждают сегодня