@puregram/scenes
Version:
Simple implementation of middleware-based scene management for puregram
94 lines (93 loc) • 3.02 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SceneContext = void 0;
const scene_types_1 = require("./scene.types");
class SceneContext {
constructor(options) {
/** Is the scene cancelled? Used in `leaveHandler()` */
this.cancelled = false;
this.lastAction = scene_types_1.LastAction.NONE;
/** Controlled behavior leave */
this.leaving = false;
this.context = options.context;
this.repository = options.repository;
this.updateSession();
}
/** Returns current scene */
get current() {
return this.repository.get(this.session.current);
}
/** Enter to scene */
async enter(slug, options = {}) {
var _a;
const scene = this.repository.strictGet(slug);
const isCurrent = ((_a = this.current) === null || _a === void 0 ? void 0 : _a.slug) === scene.slug;
if (!isCurrent) {
if (!this.leaving) {
await this.leave({
silent: options.silent
});
}
if (this.leaving) {
this.leaving = false;
this.reset();
}
}
this.lastAction = scene_types_1.LastAction.ENTER;
this.session.current = scene.slug;
Object.assign(this.state, options.state || {});
if (options.silent) {
return;
}
await scene.enterHandler(this.context);
}
/** Reenter to current scene */
async reenter() {
const { current } = this;
if (!current) {
throw new Error('there is no active scene to enter');
}
await this.enter(current.slug);
}
/** Leave from current scene */
async leave(options = {}) {
var _a;
const { current } = this;
if (!current) {
return;
}
this.leaving = true;
this.lastAction = scene_types_1.LastAction.LEAVE;
if (!options.silent) {
this.cancelled = (_a = options.cancelled) !== null && _a !== void 0 ? _a : false;
await current.leaveHandler(this.context);
}
if (this.leaving)
this.reset();
this.leaving = false;
this.cancelled = false;
}
/** Reset state/session */
reset() {
delete this.context.session.__scene;
this.updateSession();
}
/** Updates session and state is lazy */
updateSession() {
this.session = new Proxy(this.context.session.__scene || {}, {
set: (target, prop, value) => {
target[prop] = value;
this.context.session.__scene = target;
return true;
}
});
this.state = new Proxy(this.session.state || {}, {
set: (target, prop, value) => {
target[prop] = value;
this.session.state = target;
return true;
}
});
}
}
exports.SceneContext = SceneContext;