Skip to content

Commit

Permalink
Support empty sessions, release 0.3.1
Browse files Browse the repository at this point in the history
  • Loading branch information
Loskir committed Oct 21, 2022
1 parent 2ea556d commit 24dcfef
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 12 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@loskir/grammy-views",
"author": "Kirill Loskutov",
"version": "0.3.0",
"version": "0.3.1",
"main": "./out/mod.js",
"license": "MIT",
"type": "commonjs",
Expand Down
14 changes: 9 additions & 5 deletions src/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ export class View<
this.renderComposer.use(...fn);
}

onLeave(...fn: MiddlewareFn<C & ViewStateFlavor<State> & ViewNoLeaveFlavor>[]) {
onLeave(
...fn: MiddlewareFn<C & ViewStateFlavor<State> & ViewNoLeaveFlavor>[]
) {
this.leaveComposer.use(...fn);
}

Expand All @@ -61,11 +63,13 @@ export class View<
: [data: NotDefaultState<State, DefaultState>]
): MaybePromise<unknown> {
const ctx_ = ctx as C & ViewStateFlavor<State> & ViewRenderFlavor;
if (!ctx_.session.__views) {
ctx_.session.__views = {};
if (!ctx_.session) {
ctx_.session = {};
}
ctx_.session.__views.current = this.name;
ctx_.view.state = this.applyDefaultState(params[0]!);
ctx_.session.__views = {
current: this.name,
state: this.applyDefaultState(params[0]!),
};
return this.renderComposer.middleware()(ctx_, () => Promise.resolve());
}

Expand Down
27 changes: 21 additions & 6 deletions src/viewController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export interface ViewSessionData {
current?: string;
state?: ViewBaseState;
}
export interface ViewSession {
export type ViewSession = {
__views?: ViewSessionData;
}
} | undefined;

export type ViewRenderFlavor = {
view: {
Expand Down Expand Up @@ -40,19 +40,31 @@ export class ViewController<
private views: Map<string, View<C>> = new Map();

private getCurrentView(ctx: C): GenericView<C> | undefined {
return ctx.session.__views?.current
return ctx.session?.__views?.current
? this.views.get(ctx.session.__views.current)
: undefined;
}

middleware(): MiddlewareFn<C> {
const composer = new Composer<C>();
composer.lazy((ctx) => {
if (!("session" in ctx)) {
throw new Error("Cannot use views without session");
}
try {
ctx.session;
} catch (_) {
// bypass views if session is unavailable
return super.middleware();
}
ctx.view = {
get state() {
return ctx.session.__views?.state || {};
return ctx.session?.__views?.state ?? {};
},
set state(data) {
if (!ctx.session) {
ctx.session = {};
}
if (!ctx.session.__views) {
ctx.session.__views = {};
}
Expand All @@ -65,7 +77,7 @@ export class ViewController<
// in a hacky way (yes i feel bad about it)
const ctx_ = ctx as C & ViewNoLeaveFlavor;
await currentView?._leave(ctx_);
delete ctx.session.__views;
delete ctx_.session?.__views;
},
};

Expand All @@ -91,7 +103,10 @@ export class ViewController<
c
.filter((_ctx): _ctx is C & ViewRenderFlavor => true)
.use((ctx, next) => {
ctx.view.render = () => currentView._render(ctx);
ctx.view.render = async () => {
const currentView = this.getCurrentView(ctx);
await currentView?._render(ctx);
};
return next();
})
.use(currentView);
Expand Down

0 comments on commit 24dcfef

Please sign in to comment.