UNPKG

3.94 kBPlain TextView Raw
1import { Store } from "express-session";
2import { ISessionContext, ISessionsManager } from "neweb-server";
3import { Subject } from "rxjs";
4export interface ISessionsManagerConfig {
5 sessionsPath: string;
6 sessionsStorage: Store;
7}
8class SessionsManager implements ISessionsManager {
9 protected contexts: {
10 [index: string]: {
11 context: ISessionContext<any>;
12 data: {
13 [index: string]: {
14 stream: Subject<any>;
15 value: any;
16 hasValue: boolean;
17 };
18 };
19 };
20 } = {};
21 constructor(protected config: ISessionsManagerConfig) { }
22 public async getSessionContext(sessionId: string) {
23 if (!this.contexts[sessionId]) {
24 await this.createContext(sessionId);
25 }
26 return this.contexts[sessionId].context;
27 }
28 public async createContext(sessionId: string) {
29 const data: {
30 [index: string]: {
31 stream: Subject<any>;
32 value: any;
33 hasValue: boolean;
34 };
35 } = {};
36 const context: ISessionContext<any> = {
37 get: (name: string) => {
38 return data[name] && data[name].hasValue ? data[name].value : null;
39 },
40 has: (name: string) => {
41 return data[name] && data[name].hasValue;
42 },
43 get$: (name: string) => {
44 if (!data[name]) {
45 data[name] = {
46 stream: new Subject(),
47 value: undefined,
48 hasValue: false,
49 };
50 }
51 return data[name].stream;
52 },
53 set: async (name: string, value: any) => {
54 if (!data[name]) {
55 data[name] = {
56 stream: new Subject(),
57 value: undefined,
58 hasValue: false,
59 };
60 }
61 data[name].value = value;
62 data[name].hasValue = true;
63 data[name].stream.next(value);
64 await this.save(sessionId);
65 },
66 };
67 this.contexts[sessionId] = { data, context };
68 const saved = await this.get(sessionId);
69 if (saved) {
70 Object.keys(saved)
71 .map((key) => {
72 data[key] = {
73 value: saved[key],
74 hasValue: true,
75 stream: new Subject(),
76 };
77 if (key !== "id" && key !== "cookie" && key !== "__lastAccess") {
78 data[key].stream.next(saved[key]);
79 }
80 });
81 }
82 }
83 public async get(sid: string): Promise<any | null> {
84 return new Promise<any>((resolve, reject) => {
85 this.config.sessionsStorage.get(sid, (err, session) => {
86 if (err) {
87 if (err.code === "ENOENT") {
88 resolve(null);
89 return;
90 }
91 reject(err);
92 return;
93 }
94 resolve(session);
95 });
96 });
97 }
98 public async save(id: string) {
99 const data: any = {};
100 Object.keys(this.contexts[id].data).map((d) => {
101 data[d] = this.contexts[id].data[d].value;
102 });
103 return new Promise((resolve, reject) => {
104 this.config.sessionsStorage.set(id, data, (err) => {
105 if (err) {
106 reject(err);
107 return;
108 }
109 resolve();
110 });
111 });
112 }
113}
114export default SessionsManager;
115
\No newline at end of file