@randajan/koa-io-session 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,70 +1,22 @@
1
+ import {
2
+ _customOptKeys,
3
+ _errPrefix,
4
+ _privs,
5
+ generateUid,
6
+ is,
7
+ ms,
8
+ valid,
9
+ validInterval,
10
+ validObject,
11
+ validRange,
12
+ validStore
13
+ } from "./chunk-27XQ42ES.js";
14
+
1
15
  // src/class/SessionBridge.js
2
- import { EventEmitter as EventEmitter2 } from "events";
16
+ import { EventEmitter } from "events";
3
17
  import { ServerResponse } from "http";
4
18
  import { solid as solid2, virtual } from "@randajan/props";
5
19
 
6
- // src/tools.js
7
- import crypto from "crypto";
8
- var generateUid = (len = 16) => crypto.randomBytes(len).toString("base64url").slice(0, len);
9
- var is = (type, any) => typeof any === type;
10
- var valid = (type, any, req = false, msg = "argument") => {
11
- if (any == null) {
12
- if (!req) {
13
- return;
14
- }
15
- throw new Error(`${msg} require typeof '${type}'`);
16
- }
17
- if (is(type, any)) {
18
- return any;
19
- }
20
- throw new Error(`${msg} is not typeof '${type}'`);
21
- };
22
- var validRange = (min, max, any, req = false, msg = "argument") => {
23
- const num = valid("number", any, req, msg);
24
- if (num == null) {
25
- return;
26
- }
27
- if (num < min) {
28
- throw new Error(`${msg} must be greater than ${min}`);
29
- }
30
- if (num > max) {
31
- throw new Error(`${msg} must be less than ${max}`);
32
- }
33
- return num;
34
- };
35
- var validInterval = (any, req = false, msg = "argument") => {
36
- return validRange(10, 2147483647, any, req, msg);
37
- };
38
- var validObject = (any, req = false, msg = "argument") => {
39
- const obj = valid("object", any, req, msg);
40
- if (obj == null) {
41
- return;
42
- }
43
- if (!Array.isArray(obj)) {
44
- return obj;
45
- }
46
- throw new Error(`${msg} must be object, not array`);
47
- };
48
- var validStore = (store) => {
49
- const missing = [];
50
- if (!is("function", store?.get)) {
51
- missing.push("get()");
52
- }
53
- if (!is("function", store?.set)) {
54
- missing.push("set()");
55
- }
56
- if (!is("function", store?.destroy)) {
57
- missing.push("destroy()");
58
- }
59
- if (!is("function", store?.on)) {
60
- missing.push("on()");
61
- }
62
- if (missing.length) {
63
- throw new TypeError(`store is missing required API: ${missing.join(", ")}`);
64
- }
65
- return store;
66
- };
67
-
68
20
  // src/httpSession.js
69
21
  import session from "koa-session";
70
22
 
@@ -88,10 +40,11 @@ var wrapExternalKey = (opt, onSet) => {
88
40
  };
89
41
 
90
42
  // src/httpSession.js
91
- var createKoaSession = (opt, app, onSet) => {
92
- const store = wrapStore(opt.store);
43
+ var createKoaSession = (app, gw, opt, onSet) => {
44
+ const maxAge = gw.maxAge;
45
+ const store = wrapStore(gw);
93
46
  const externalKey = wrapExternalKey(opt, onSet);
94
- const koaSession = session({ ...opt, store, externalKey }, app);
47
+ const koaSession = session({ ...opt, maxAge, store, externalKey }, app);
95
48
  return [koaSession, externalKey];
96
49
  };
97
50
  var createClientCookie = (opt) => {
@@ -111,41 +64,6 @@ var createClientCookie = (opt) => {
111
64
  // src/socketSession.js
112
65
  import { solids } from "@randajan/props";
113
66
  var sidLocks = /* @__PURE__ */ new Map();
114
- var createSessionCtx = (sessionId, session2, socket) => solids({ session: session2 }, { sessionId, socket });
115
- var createSessionHash = (session2) => {
116
- try {
117
- return JSON.stringify(session2 ?? null);
118
- } catch {
119
- return null;
120
- }
121
- };
122
- var isSessionHashChanged = (originalHash, session2) => {
123
- const nextHash = createSessionHash(session2);
124
- if (originalHash == null || nextHash == null) {
125
- return true;
126
- }
127
- return originalHash !== nextHash;
128
- };
129
- var withLock = async (task, socket, ...args) => {
130
- const sid = socket.sessionId;
131
- const previous = sidLocks.get(sid);
132
- let releaseCurrent;
133
- const current = new Promise((resolve) => {
134
- releaseCurrent = resolve;
135
- });
136
- sidLocks.set(sid, current);
137
- if (previous) {
138
- await previous;
139
- }
140
- try {
141
- return await task(socket, ...args);
142
- } finally {
143
- releaseCurrent();
144
- if (sidLocks.get(sid) === current) {
145
- sidLocks.delete(sid);
146
- }
147
- }
148
- };
149
67
  var applyOnMissing = (onMissing) => {
150
68
  if (onMissing instanceof Error) {
151
69
  throw onMissing;
@@ -155,126 +73,55 @@ var applyOnMissing = (onMissing) => {
155
73
  }
156
74
  return onMissing;
157
75
  };
158
- var runSessionHandler = async (socket, handler, store, onMissing) => {
159
- const sid = socket.sessionId;
160
- const current = await store.get(sid);
161
- if (!current) {
76
+ var runSessionHandler = async (sid, socket, handler, gw, onMissing) => {
77
+ const session2 = await gw.get(sid);
78
+ if (!session2) {
162
79
  return applyOnMissing(onMissing);
163
80
  }
164
- const session2 = current;
165
- const sessionCtx = createSessionCtx(sid, session2, socket);
166
- const originalHash = createSessionHash(sessionCtx.session);
81
+ const sessionCtx = solids({ session: session2 }, { sessionId: sid, socket });
167
82
  const result = await handler(sessionCtx, socket);
168
- if (sessionCtx.session == null) {
169
- await store.destroy(sid);
170
- return result;
171
- }
172
- sessionCtx.session = validObject(sessionCtx.session, false, "session");
173
- if (isSessionHashChanged(originalHash, sessionCtx.session)) {
174
- await store.set(sid, sessionCtx.session);
83
+ if (sid === socket.sessionId) {
84
+ await gw.set(sid, sessionCtx.session);
175
85
  }
176
86
  return result;
177
87
  };
178
- var applySessionHandler = async (socket, handler, store, onMissing) => {
179
- if (typeof handler !== "function") {
180
- throw new TypeError("socket.withSession(handler) requires a function");
181
- }
182
- if (!socket.sessionId) {
183
- return applyOnMissing(onMissing);
184
- }
185
- return withLock(runSessionHandler, socket, handler, store, onMissing);
186
- };
187
-
188
- // src/class/SessionStore.js
189
- import { solid } from "@randajan/props";
190
- import { EventEmitter } from "events";
191
-
192
- // src/const.js
193
- var ms = {
194
- s: (v = 1) => v * 1e3,
195
- m: (v = 1) => ms.s(v * 60),
196
- h: (v = 1) => ms.m(v * 60),
197
- d: (v = 1) => ms.h(v * 24),
198
- w: (v = 1) => ms.d(v * 7),
199
- M: (v = 1) => ms.d(v * 30),
200
- y: (v = 1) => ms.d(v * 365)
201
- };
202
- var _customOptKeys = /* @__PURE__ */ new Set([
203
- "store",
204
- "autoCleanup",
205
- "autoCleanupMs",
206
- "clientKey",
207
- "clientMaxAge",
208
- "clientAlwaysRoll"
209
- ]);
210
-
211
- // src/class/SessionStore.js
212
- var formatState = (session2, maxAge, prevTTL, maxAgeDefault) => {
213
- const ttl = maxAge ?? prevTTL ?? maxAgeDefault;
214
- const expiresAt = Date.now() + ttl;
215
- return { session: session2, expiresAt, ttl };
216
- };
217
- var SessionStore = class extends Map {
218
- constructor(opt = {}) {
219
- super();
220
- const maxAge = validRange(ms.s(), ms.y(), opt.maxAge, false, "maxAge") ?? ms.M();
221
- const autoCleanup = valid("boolean", opt.autoCleanup, false, "autoCleanup") ?? true;
222
- const autoCleanupMs = validInterval(opt.autoCleanupMs, false, "autoCleanupMs") ?? Math.max(ms.s(), Math.min(ms.h(), maxAge / 10));
223
- solid(this, "maxAge", maxAge);
224
- solid(this, "event", new EventEmitter());
225
- if (!autoCleanup) {
226
- return;
227
- }
228
- setInterval((_) => this.cleanup(), autoCleanupMs);
229
- }
230
- on(eventName, callback) {
231
- return this.event.on(eventName, callback);
232
- }
233
- get(sid) {
234
- const d = super.get(sid);
235
- if (!d) {
236
- return;
237
- }
238
- if (Date.now() < d.expiresAt) {
239
- return d.session;
88
+ var createLock = (sid) => {
89
+ let _release;
90
+ const previous = sidLocks.get(sid);
91
+ const current = new Promise((resolve) => {
92
+ _release = resolve;
93
+ });
94
+ sidLocks.set(sid, current);
95
+ const release = () => {
96
+ _release();
97
+ if (sidLocks.get(sid) === current) {
98
+ sidLocks.delete(sid);
240
99
  }
241
- this.delete(sid);
242
- }
243
- set(sid, session2, maxAge) {
244
- const d = super.get(sid);
245
- if (session2 == null) {
246
- return !d || this.destroy(sid);
100
+ };
101
+ return [previous, release];
102
+ };
103
+ var applySessionHandler = async (socket, handler, gw, onMissing) => {
104
+ valid("function", handler, true, "handler");
105
+ for (let i = 0; i < 5; i++) {
106
+ const sid = socket.sessionId;
107
+ if (!sid) {
108
+ return applyOnMissing(onMissing);
247
109
  }
248
- super.set(sid, formatState(session2, maxAge, d?.ttl, this.maxAge));
249
- this.event.emit("set", this, sid, !d);
250
- return true;
251
- }
252
- delete(sid) {
253
- return this.destroy(sid);
254
- }
255
- destroy(sid) {
256
- if (this.has(sid)) {
257
- super.delete(sid);
258
- this.event.emit("destroy", this, sid);
110
+ const [previous, release] = createLock(sid);
111
+ if (previous) {
112
+ await previous;
259
113
  }
260
- return true;
261
- }
262
- cleanup() {
263
- const now = Date.now();
264
- let cleared = 0;
265
- for (const [sid, d] of this.entries()) {
266
- if (now < d.expiresAt) {
267
- continue;
268
- }
269
- if (this.destroy(sid)) {
270
- cleared++;
271
- }
114
+ if (previous && sid !== socket.sessionId) {
115
+ release();
116
+ continue;
272
117
  }
273
- if (cleared) {
274
- this.event.emit("cleanup", this, cleared);
118
+ try {
119
+ return await runSessionHandler(sid, socket, handler, gw, onMissing);
120
+ } finally {
121
+ release();
275
122
  }
276
- return cleared;
277
123
  }
124
+ throw new Error(`${_errPrefix} socket.sessionId changed during withSession execution.`);
278
125
  };
279
126
 
280
127
  // src/formatOptions.js
@@ -287,9 +134,7 @@ var pickKoaOpt = (rawOpt) => {
287
134
  koaOpt[key] = rawOpt[key];
288
135
  }
289
136
  koaOpt.key = valid("string", koaOpt.key, false, "key") ?? generateUid(12);
290
- koaOpt.maxAge = validRange(ms.s(), ms.y(), koaOpt.maxAge, false, "maxAge") ?? ms.M();
291
137
  koaOpt.signed = valid("boolean", koaOpt.signed, false, "signed") ?? true;
292
- koaOpt.store = validStore(rawOpt.store || new SessionStore(rawOpt));
293
138
  return koaOpt;
294
139
  };
295
140
  var formatOptions = (opt = {}) => {
@@ -329,7 +174,7 @@ var Bridge = class {
329
174
  }
330
175
  this.c2s.set(cid, sid);
331
176
  this.s2c.set(sid, cid);
332
- this.onSet({ clientId: cid, sessionId: sid });
177
+ this.onSet(cid, sid);
333
178
  return true;
334
179
  }
335
180
  getByCid(cid) {
@@ -348,7 +193,7 @@ var Bridge = class {
348
193
  }
349
194
  this.s2c.delete(sid);
350
195
  this.c2s.delete(cid);
351
- this.onDelete({ clientId: cid, sessionId: sid });
196
+ this.onDelete(cid, sid);
352
197
  return true;
353
198
  }
354
199
  deleteByCid(cid, skipIf) {
@@ -361,30 +206,245 @@ var Bridge = class {
361
206
  }
362
207
  this.c2s.delete(cid);
363
208
  this.s2c.delete(sid);
364
- this.onDelete({ clientId: cid, sessionId: sid });
209
+ this.onDelete(cid, sid);
210
+ return true;
211
+ }
212
+ };
213
+
214
+ // src/class/TempMap.js
215
+ var TempMap = class extends Map {
216
+ constructor(ttl) {
217
+ super();
218
+ const _p = {
219
+ ttl: validInterval(ttl, true, "ttl"),
220
+ ts: /* @__PURE__ */ new Map()
221
+ };
222
+ _privs.set(this, _p);
223
+ }
224
+ set(key, value, overwrite = true) {
225
+ const { ts, ttl } = _privs.get(this);
226
+ if (!overwrite && this.has(key)) {
227
+ return false;
228
+ }
229
+ this.delete(key);
230
+ super.set(key, value);
231
+ const t = setTimeout((_) => {
232
+ this.delete(key);
233
+ }, ttl);
234
+ ts.set(key, t);
235
+ return true;
236
+ }
237
+ get(key, andDelete = false) {
238
+ const v = super.get(key);
239
+ if (andDelete) {
240
+ this.delete(key);
241
+ }
242
+ return v;
243
+ }
244
+ delete(key) {
245
+ if (!super.delete(key)) {
246
+ return false;
247
+ }
248
+ const { ts } = _privs.get(this);
249
+ const t = ts.get(key);
250
+ clearTimeout(t);
251
+ ts.delete(key);
252
+ return true;
253
+ }
254
+ };
255
+
256
+ // src/class/StoreGateway.js
257
+ import { solid } from "@randajan/props";
258
+
259
+ // src/stores/LiveStore.js
260
+ var LiveStore = class extends Map {
261
+ get(sid) {
262
+ return super.get(sid);
263
+ }
264
+ set(sid, state) {
265
+ super.set(sid, state);
266
+ return true;
267
+ }
268
+ destroy(sid) {
269
+ return super.delete(sid);
270
+ }
271
+ list() {
272
+ return this.keys();
273
+ }
274
+ };
275
+
276
+ // src/class/StoreGateway.js
277
+ var formatState = (session2, maxAge, maxAgeDefault) => {
278
+ const ttl = maxAge ?? maxAgeDefault;
279
+ const expiresAt = Date.now() + ttl;
280
+ return { session: session2, expiresAt, ttl };
281
+ };
282
+ var requireList = (store) => {
283
+ if (!store.list) {
284
+ throw new TypeError(`${_errPrefix} store.list() is required`);
285
+ }
286
+ };
287
+ var StoreGateway = class _StoreGateway {
288
+ static is(any) {
289
+ return any instanceof _StoreGateway;
290
+ }
291
+ constructor(opt = {}, emit = {}) {
292
+ const maxAge = validRange(opt.maxAge, ms.m(), ms.y(), false, "maxAge") ?? ms.M();
293
+ const autoCleanup = valid("boolean", opt.autoCleanup, false, "autoCleanup") ?? false;
294
+ solid(this, "emit", emit);
295
+ solid(this, "maxAge", maxAge);
296
+ solid(this, "store", validStore(opt.store, false) ?? new LiveStore());
297
+ if (autoCleanup) {
298
+ this.startAutoCleanup(validInterval(opt.autoCleanupMs, false, "autoCleanupMs"));
299
+ }
300
+ }
301
+ async list() {
302
+ const { store } = this;
303
+ requireList(store);
304
+ return store.list();
305
+ }
306
+ async get(sid) {
307
+ const { store } = this;
308
+ const c = await store.get(sid);
309
+ if (!c) {
310
+ return;
311
+ }
312
+ if (Date.now() >= c.expiresAt) {
313
+ await this.destroy(sid);
314
+ return;
315
+ }
316
+ try {
317
+ return JSON.parse(c.session);
318
+ } catch {
319
+ await this.destroy(sid);
320
+ throw new Error(`${_errPrefix} Invalid session JSON for sid='${sid}'.`);
321
+ }
322
+ ;
323
+ }
324
+ async set(sid, session2, maxAge) {
325
+ const { store } = this;
326
+ const ses = validObject(session2, false, "session");
327
+ if (ses == null) {
328
+ return this.destroy(sid);
329
+ }
330
+ const to = JSON.stringify(ses);
331
+ const from = await store.get(sid, false);
332
+ if (to === from?.session) {
333
+ return true;
334
+ }
335
+ const isOk = await store.set(sid, formatState(to, maxAge, this.maxAge));
336
+ if (isOk === false) {
337
+ return false;
338
+ }
339
+ this.emit.notifySet(sid, !from);
340
+ return true;
341
+ }
342
+ async destroy(sid) {
343
+ const { store } = this;
344
+ const isOk = await store.destroy(sid);
345
+ if (isOk === false) {
346
+ return false;
347
+ }
348
+ this.emit.notifyDestroy(sid);
349
+ return true;
350
+ }
351
+ async cleanup() {
352
+ const { store } = this;
353
+ requireList(store);
354
+ const list = await store.list();
355
+ const now = Date.now();
356
+ let cleared = 0;
357
+ await Promise.all([...list].map(async (sid) => {
358
+ const d = await store.get(sid);
359
+ if (!d) {
360
+ return;
361
+ }
362
+ if (now < d.expiresAt) {
363
+ return;
364
+ }
365
+ if (await this.destroy(sid)) {
366
+ cleared++;
367
+ }
368
+ }));
369
+ if (is("function", store.optimize)) {
370
+ await store.optimize(cleared);
371
+ }
372
+ this.emit.notifyCleanup(cleared);
373
+ return cleared;
374
+ }
375
+ startAutoCleanup(interval) {
376
+ const { store, maxAge, _intId } = this;
377
+ requireList(store);
378
+ const int = validRange(interval, ms.m(), ms.d(), false, "interval") ?? Math.max(ms.m(), Math.min(ms.d(), maxAge / 4));
379
+ clearInterval(_intId);
380
+ this._intId = setInterval((_) => this.cleanup().catch(() => {
381
+ }), int);
382
+ return true;
383
+ }
384
+ stopAutoCleanup() {
385
+ const { _intId } = this;
386
+ if (!_intId) {
387
+ return false;
388
+ }
389
+ clearInterval(_intId);
390
+ delete this._intId;
365
391
  return true;
366
392
  }
367
393
  };
368
394
 
369
395
  // src/class/SessionBridge.js
370
- var SessionBridge = class extends EventEmitter2 {
396
+ var SessionBridge = class extends EventEmitter {
371
397
  constructor(app, io, opt = {}) {
372
398
  super();
373
399
  if (!app.keys) {
374
400
  app.keys = Array(6).fill().map(() => generateUid(12));
375
401
  }
376
- const o = formatOptions(opt);
377
- const { store } = o.koaOpt;
378
- const brg = new Bridge({
379
- onSet: (pair) => this.emit("sessionStart", pair),
380
- onDelete: (pair) => this.emit("sessionEnd", pair)
402
+ const { koaOpt, clientOpt, clientAlwaysRoll } = formatOptions(opt);
403
+ const _p = {};
404
+ const tmp = new TempMap(5e3);
405
+ const brg = _p.brg = new Bridge({
406
+ onSet: (clientId, sessionId) => {
407
+ const isNew = !!tmp.get(sessionId, true);
408
+ this.emit("sessionSet", { clientId, sessionId, isNew, isInit: true });
409
+ },
410
+ onDelete: (clientId, sessionId) => this.emit("sessionDestroy", { clientId, sessionId })
381
411
  });
382
- const cc = createClientCookie(o.clientOpt);
383
- const [koaSession, sc] = createKoaSession(o.koaOpt, app, (ctx, sid) => {
412
+ _p.notifySet = (sid, isNew) => {
413
+ if (!sid) {
414
+ return;
415
+ }
416
+ const cid = brg.getBySid(sid);
417
+ if (!cid) {
418
+ tmp.set(sid, isNew, false);
419
+ return;
420
+ }
421
+ this.emit("sessionSet", { clientId: cid, sessionId: sid, isNew: !!isNew, isInit: false });
422
+ };
423
+ _p.notifyDestroy = (sid) => {
424
+ if (sid) {
425
+ brg.deleteBySid(sid);
426
+ }
427
+ };
428
+ _p.notifyCleanup = (cleared) => {
429
+ this.emit("cleanup", cleared);
430
+ };
431
+ const gw = _p.gw = new StoreGateway(opt, _p);
432
+ const cc = createClientCookie(clientOpt);
433
+ const [koaSession, sc] = createKoaSession(app, gw, koaOpt, (ctx, sid) => {
384
434
  const cid = cc.get(ctx);
385
435
  brg.set(cid, sid);
386
436
  });
387
- const regenerateSid = async (ctx, cid, reqSid) => {
437
+ const reviveCid = (ctx) => {
438
+ let cid = cc.get(ctx);
439
+ if (!cid) {
440
+ cc.set(ctx, cid = generateUid(24));
441
+ } else if (clientAlwaysRoll) {
442
+ cc.set(ctx, cid);
443
+ }
444
+ return cid;
445
+ };
446
+ const reviveSid = async (ctx, cid) => {
447
+ const reqSid = sc.get(ctx);
388
448
  if (cid == null || reqSid == null) {
389
449
  return;
390
450
  }
@@ -398,21 +458,15 @@ var SessionBridge = class extends EventEmitter2 {
398
458
  if (brg.getBySid(reqSid)) {
399
459
  return;
400
460
  }
401
- if (!await store.get(reqSid)) {
461
+ if (!await gw.get(reqSid)) {
402
462
  return;
403
463
  }
404
464
  brg.set(cid, reqSid);
405
465
  };
406
466
  app.use(koaSession);
407
467
  app.use(async (ctx, next) => {
408
- let cid = cc.get(ctx);
409
- const sid = sc.get(ctx);
410
- if (!cid) {
411
- cc.set(ctx, cid = generateUid(24));
412
- } else if (o.clientAlwaysRoll) {
413
- cc.set(ctx, cid);
414
- }
415
- await regenerateSid(ctx, cid, sid);
468
+ const cid = reviveCid(ctx);
469
+ await reviveSid(ctx, cid);
416
470
  solid2(ctx, "clientId", cid);
417
471
  virtual(ctx, "sessionId", (_) => brg.getByCid(cid));
418
472
  await next();
@@ -423,24 +477,87 @@ var SessionBridge = class extends EventEmitter2 {
423
477
  const ctx = app.createContext(req, res);
424
478
  await koaSession(ctx, async () => {
425
479
  });
426
- const cid = cc.get(ctx);
427
- const sid = sc.get(ctx);
428
- await regenerateSid(ctx, cid, sid);
480
+ const cid = reviveCid(ctx);
481
+ await reviveSid(ctx, cid);
429
482
  solid2(socket, "clientId", cid);
430
483
  virtual(socket, "sessionId", (_) => brg.getByCid(cid));
431
484
  solid2(socket, "withSession", async function(handler, onMissing) {
432
- const onm = arguments.length > 1 ? onMissing : new Error("Session missing");
433
- return applySessionHandler(socket, handler, store, onm);
485
+ const onm = arguments.length > 1 ? onMissing : new Error(`${_errPrefix} Session is missing for this socket.`);
486
+ return applySessionHandler(socket, handler, gw, onm);
434
487
  }, false);
435
488
  await next();
436
489
  });
437
- store.on("destroy", (_store, sid) => {
438
- if (!sid) {
439
- return;
440
- }
441
- brg.deleteBySid(sid);
442
- });
443
- solid2(this, "store", store);
490
+ _privs.set(this, _p);
491
+ }
492
+ async getById(sessionId) {
493
+ const { gw, brg } = _privs.get(this);
494
+ const cid = brg.getBySid(sessionId);
495
+ if (cid) {
496
+ return gw.get(sessionId);
497
+ }
498
+ }
499
+ async destroyById(sessionId) {
500
+ const { gw, brg } = _privs.get(this);
501
+ const cid = brg.getBySid(sessionId);
502
+ if (cid) {
503
+ return gw.destroy(sessionId);
504
+ }
505
+ return false;
506
+ }
507
+ async setById(sessionId, session2, maxAge) {
508
+ const { gw, brg } = _privs.get(this);
509
+ const cid = brg.getBySid(sessionId);
510
+ if (cid) {
511
+ return gw.set(sessionId, session2, maxAge);
512
+ }
513
+ throw new Error(`${_errPrefix} Creating session via setById() is prohibited. sessionId='${sessionId}'.`);
514
+ }
515
+ async getByClientId(clientId) {
516
+ const { gw, brg } = _privs.get(this);
517
+ const sid = brg.getByCid(clientId);
518
+ if (sid) {
519
+ return gw.get(sid);
520
+ }
521
+ }
522
+ async destroyByClientId(clientId) {
523
+ const { gw, brg } = _privs.get(this);
524
+ const sid = brg.getByCid(clientId);
525
+ if (sid) {
526
+ return gw.destroy(sid);
527
+ }
528
+ return false;
529
+ }
530
+ async setByClientId(clientId, session2, maxAge) {
531
+ const { gw, brg } = _privs.get(this);
532
+ const sid = brg.getByCid(clientId);
533
+ if (sid) {
534
+ return gw.set(sid, session2, maxAge);
535
+ }
536
+ throw new Error(`${_errPrefix} Creating session via setByClientId() is prohibited. clientId='${clientId}'.`);
537
+ }
538
+ getSessionId(clientId) {
539
+ return _privs.get(this).brg.getByCid(clientId);
540
+ }
541
+ getClientId(sessionId) {
542
+ return _privs.get(this).brg.getBySid(sessionId);
543
+ }
544
+ async cleanup() {
545
+ return _privs.get(this).gw.cleanup();
546
+ }
547
+ startAutoCleanup(interval) {
548
+ return _privs.get(this).gw.startAutoCleanup(interval);
549
+ }
550
+ stopAutoCleanup() {
551
+ return _privs.get(this).gw.stopAutoCleanup();
552
+ }
553
+ notifyStoreSet(sessionId, isNew) {
554
+ return _privs.get(this).notifySet(sessionId, isNew);
555
+ }
556
+ notifyStoreDestroy(sessionId) {
557
+ return _privs.get(this).notifyDestroy(sessionId);
558
+ }
559
+ notifyStoreCleanup(clearedCount) {
560
+ return _privs.get(this).notifyCleanup(clearedCount);
444
561
  }
445
562
  };
446
563
 
@@ -448,10 +565,11 @@ var SessionBridge = class extends EventEmitter2 {
448
565
  var bridgeSession = (app, io, opt = {}) => new SessionBridge(app, io, opt);
449
566
  var index_default = bridgeSession;
450
567
  export {
568
+ LiveStore,
451
569
  SessionBridge,
452
- SessionStore,
453
570
  bridgeSession,
454
571
  index_default as default,
455
- generateUid
572
+ generateUid,
573
+ ms
456
574
  };
457
575
  //# sourceMappingURL=index.js.map