@apibara/plugin-mongo 2.0.0-beta.37 → 2.0.0-beta.39

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.
package/dist/index.cjs CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  const indexer = require('@apibara/indexer');
4
4
  const plugins = require('@apibara/indexer/plugins');
5
+ const internal = require('@apibara/indexer/internal');
6
+ const plugins$1 = require('@apibara/indexer/internal/plugins');
5
7
 
6
8
  async function invalidate(db, session, cursor, collections) {
7
9
  const orderKeyValue = Number(cursor.orderKey);
@@ -51,10 +53,10 @@ async function initializePersistentState(db, session) {
51
53
  await filter.createIndex({ id: 1, fromBlock: 1 }, { session });
52
54
  }
53
55
  async function persistState(props) {
54
- const { db, session, endCursor, filter, indexerName } = props;
56
+ const { db, session, endCursor, filter, indexerId } = props;
55
57
  if (endCursor) {
56
58
  await db.collection(checkpointCollectionName).updateOne(
57
- { id: indexerName },
59
+ { id: indexerId },
58
60
  {
59
61
  $set: {
60
62
  orderKey: Number(endCursor.orderKey),
@@ -65,13 +67,13 @@ async function persistState(props) {
65
67
  );
66
68
  if (filter) {
67
69
  await db.collection(filterCollectionName).updateMany(
68
- { id: indexerName, toBlock: null },
70
+ { id: indexerId, toBlock: null },
69
71
  { $set: { toBlock: Number(endCursor.orderKey) } },
70
72
  { session }
71
73
  );
72
74
  await db.collection(filterCollectionName).updateOne(
73
75
  {
74
- id: indexerName,
76
+ id: indexerId,
75
77
  fromBlock: Number(endCursor.orderKey)
76
78
  },
77
79
  {
@@ -87,10 +89,10 @@ async function persistState(props) {
87
89
  }
88
90
  }
89
91
  async function getState(props) {
90
- const { db, session, indexerName } = props;
92
+ const { db, session, indexerId } = props;
91
93
  let cursor;
92
94
  let filter;
93
- const checkpointRow = await db.collection(checkpointCollectionName).findOne({ id: indexerName }, { session });
95
+ const checkpointRow = await db.collection(checkpointCollectionName).findOne({ id: indexerId }, { session });
94
96
  if (checkpointRow) {
95
97
  cursor = {
96
98
  orderKey: BigInt(checkpointRow.orderKey),
@@ -99,7 +101,7 @@ async function getState(props) {
99
101
  }
100
102
  const filterRow = await db.collection(filterCollectionName).findOne(
101
103
  {
102
- id: indexerName,
104
+ id: indexerId,
103
105
  toBlock: null
104
106
  },
105
107
  { session }
@@ -110,22 +112,22 @@ async function getState(props) {
110
112
  return { cursor, filter };
111
113
  }
112
114
  async function invalidateState(props) {
113
- const { db, session, cursor, indexerName } = props;
115
+ const { db, session, cursor, indexerId } = props;
114
116
  await db.collection(filterCollectionName).deleteMany(
115
- { id: indexerName, fromBlock: { $gt: Number(cursor.orderKey) } },
117
+ { id: indexerId, fromBlock: { $gt: Number(cursor.orderKey) } },
116
118
  { session }
117
119
  );
118
120
  await db.collection(filterCollectionName).updateMany(
119
- { id: indexerName, toBlock: { $gt: Number(cursor.orderKey) } },
121
+ { id: indexerId, toBlock: { $gt: Number(cursor.orderKey) } },
120
122
  { $set: { toBlock: null } },
121
123
  { session }
122
124
  );
123
125
  }
124
126
  async function finalizeState(props) {
125
- const { db, session, cursor, indexerName } = props;
127
+ const { db, session, cursor, indexerId } = props;
126
128
  await db.collection(filterCollectionName).deleteMany(
127
129
  {
128
- id: indexerName,
130
+ id: indexerId,
129
131
  toBlock: { $lte: Number(cursor.orderKey) }
130
132
  },
131
133
  { session }
@@ -332,10 +334,13 @@ function mongoStorage({
332
334
  dbOptions,
333
335
  collections,
334
336
  persistState: enablePersistence = true,
335
- indexerName = "default"
337
+ indexerName: identifier = "default"
336
338
  }) {
337
339
  return plugins.defineIndexerPlugin((indexer) => {
340
+ let indexerId = "";
338
341
  indexer.hooks.hook("run:before", async () => {
342
+ const { indexerName } = plugins$1.useInternalContext();
343
+ indexerId = internal.generateIndexerId(indexerName, identifier);
339
344
  await withTransaction(client, async (session) => {
340
345
  const db = client.db(dbName, dbOptions);
341
346
  if (enablePersistence) {
@@ -352,7 +357,7 @@ function mongoStorage({
352
357
  const { cursor, filter } = await getState({
353
358
  db,
354
359
  session,
355
- indexerName
360
+ indexerId
356
361
  });
357
362
  if (cursor) {
358
363
  request.startingCursor = cursor;
@@ -371,7 +376,7 @@ function mongoStorage({
371
376
  const db = client.db(dbName, dbOptions);
372
377
  await invalidate(db, session, cursor, collections);
373
378
  if (enablePersistence) {
374
- await invalidateState({ db, session, cursor, indexerName });
379
+ await invalidateState({ db, session, cursor, indexerId });
375
380
  }
376
381
  });
377
382
  });
@@ -387,7 +392,7 @@ function mongoStorage({
387
392
  endCursor,
388
393
  session,
389
394
  filter: request.filter[1],
390
- indexerName
395
+ indexerId
391
396
  });
392
397
  }
393
398
  });
@@ -401,7 +406,7 @@ function mongoStorage({
401
406
  const db = client.db(dbName, dbOptions);
402
407
  await finalize(db, session, cursor, collections);
403
408
  if (enablePersistence) {
404
- await finalizeState({ db, session, cursor, indexerName });
409
+ await finalizeState({ db, session, cursor, indexerId });
405
410
  }
406
411
  });
407
412
  });
@@ -414,7 +419,7 @@ function mongoStorage({
414
419
  const db = client.db(dbName, dbOptions);
415
420
  await invalidate(db, session, cursor, collections);
416
421
  if (enablePersistence) {
417
- await invalidateState({ db, session, cursor, indexerName });
422
+ await invalidateState({ db, session, cursor, indexerId });
418
423
  }
419
424
  });
420
425
  });
@@ -430,7 +435,12 @@ function mongoStorage({
430
435
  await next();
431
436
  delete context[MONGO_PROPERTY];
432
437
  if (enablePersistence) {
433
- await persistState({ db, endCursor, session, indexerName });
438
+ await persistState({
439
+ db,
440
+ endCursor,
441
+ session,
442
+ indexerId
443
+ });
434
444
  }
435
445
  });
436
446
  });
package/dist/index.d.cts CHANGED
@@ -44,6 +44,6 @@ interface MongoStorageOptions {
44
44
  * @param options.persistState - Whether to persist the indexer's state. Defaults to true.
45
45
  * @param options.indexerName - The name of the indexer. Defaults value is 'default'.
46
46
  */
47
- declare function mongoStorage<TFilter, TBlock>({ client, dbName, dbOptions, collections, persistState: enablePersistence, indexerName, }: MongoStorageOptions): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
47
+ declare function mongoStorage<TFilter, TBlock>({ client, dbName, dbOptions, collections, persistState: enablePersistence, indexerName: identifier, }: MongoStorageOptions): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
48
48
 
49
49
  export { MongoCollection, MongoStorage, type MongoStorageOptions, mongoStorage, useMongoStorage };
package/dist/index.d.mts CHANGED
@@ -44,6 +44,6 @@ interface MongoStorageOptions {
44
44
  * @param options.persistState - Whether to persist the indexer's state. Defaults to true.
45
45
  * @param options.indexerName - The name of the indexer. Defaults value is 'default'.
46
46
  */
47
- declare function mongoStorage<TFilter, TBlock>({ client, dbName, dbOptions, collections, persistState: enablePersistence, indexerName, }: MongoStorageOptions): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
47
+ declare function mongoStorage<TFilter, TBlock>({ client, dbName, dbOptions, collections, persistState: enablePersistence, indexerName: identifier, }: MongoStorageOptions): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
48
48
 
49
49
  export { MongoCollection, MongoStorage, type MongoStorageOptions, mongoStorage, useMongoStorage };
package/dist/index.d.ts CHANGED
@@ -44,6 +44,6 @@ interface MongoStorageOptions {
44
44
  * @param options.persistState - Whether to persist the indexer's state. Defaults to true.
45
45
  * @param options.indexerName - The name of the indexer. Defaults value is 'default'.
46
46
  */
47
- declare function mongoStorage<TFilter, TBlock>({ client, dbName, dbOptions, collections, persistState: enablePersistence, indexerName, }: MongoStorageOptions): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
47
+ declare function mongoStorage<TFilter, TBlock>({ client, dbName, dbOptions, collections, persistState: enablePersistence, indexerName: identifier, }: MongoStorageOptions): _apibara_indexer_plugins.IndexerPlugin<TFilter, TBlock>;
48
48
 
49
49
  export { MongoCollection, MongoStorage, type MongoStorageOptions, mongoStorage, useMongoStorage };
package/dist/index.mjs CHANGED
@@ -1,5 +1,7 @@
1
1
  import { useIndexerContext } from '@apibara/indexer';
2
2
  import { defineIndexerPlugin } from '@apibara/indexer/plugins';
3
+ import { generateIndexerId } from '@apibara/indexer/internal';
4
+ import { useInternalContext } from '@apibara/indexer/internal/plugins';
3
5
 
4
6
  async function invalidate(db, session, cursor, collections) {
5
7
  const orderKeyValue = Number(cursor.orderKey);
@@ -49,10 +51,10 @@ async function initializePersistentState(db, session) {
49
51
  await filter.createIndex({ id: 1, fromBlock: 1 }, { session });
50
52
  }
51
53
  async function persistState(props) {
52
- const { db, session, endCursor, filter, indexerName } = props;
54
+ const { db, session, endCursor, filter, indexerId } = props;
53
55
  if (endCursor) {
54
56
  await db.collection(checkpointCollectionName).updateOne(
55
- { id: indexerName },
57
+ { id: indexerId },
56
58
  {
57
59
  $set: {
58
60
  orderKey: Number(endCursor.orderKey),
@@ -63,13 +65,13 @@ async function persistState(props) {
63
65
  );
64
66
  if (filter) {
65
67
  await db.collection(filterCollectionName).updateMany(
66
- { id: indexerName, toBlock: null },
68
+ { id: indexerId, toBlock: null },
67
69
  { $set: { toBlock: Number(endCursor.orderKey) } },
68
70
  { session }
69
71
  );
70
72
  await db.collection(filterCollectionName).updateOne(
71
73
  {
72
- id: indexerName,
74
+ id: indexerId,
73
75
  fromBlock: Number(endCursor.orderKey)
74
76
  },
75
77
  {
@@ -85,10 +87,10 @@ async function persistState(props) {
85
87
  }
86
88
  }
87
89
  async function getState(props) {
88
- const { db, session, indexerName } = props;
90
+ const { db, session, indexerId } = props;
89
91
  let cursor;
90
92
  let filter;
91
- const checkpointRow = await db.collection(checkpointCollectionName).findOne({ id: indexerName }, { session });
93
+ const checkpointRow = await db.collection(checkpointCollectionName).findOne({ id: indexerId }, { session });
92
94
  if (checkpointRow) {
93
95
  cursor = {
94
96
  orderKey: BigInt(checkpointRow.orderKey),
@@ -97,7 +99,7 @@ async function getState(props) {
97
99
  }
98
100
  const filterRow = await db.collection(filterCollectionName).findOne(
99
101
  {
100
- id: indexerName,
102
+ id: indexerId,
101
103
  toBlock: null
102
104
  },
103
105
  { session }
@@ -108,22 +110,22 @@ async function getState(props) {
108
110
  return { cursor, filter };
109
111
  }
110
112
  async function invalidateState(props) {
111
- const { db, session, cursor, indexerName } = props;
113
+ const { db, session, cursor, indexerId } = props;
112
114
  await db.collection(filterCollectionName).deleteMany(
113
- { id: indexerName, fromBlock: { $gt: Number(cursor.orderKey) } },
115
+ { id: indexerId, fromBlock: { $gt: Number(cursor.orderKey) } },
114
116
  { session }
115
117
  );
116
118
  await db.collection(filterCollectionName).updateMany(
117
- { id: indexerName, toBlock: { $gt: Number(cursor.orderKey) } },
119
+ { id: indexerId, toBlock: { $gt: Number(cursor.orderKey) } },
118
120
  { $set: { toBlock: null } },
119
121
  { session }
120
122
  );
121
123
  }
122
124
  async function finalizeState(props) {
123
- const { db, session, cursor, indexerName } = props;
125
+ const { db, session, cursor, indexerId } = props;
124
126
  await db.collection(filterCollectionName).deleteMany(
125
127
  {
126
- id: indexerName,
128
+ id: indexerId,
127
129
  toBlock: { $lte: Number(cursor.orderKey) }
128
130
  },
129
131
  { session }
@@ -330,10 +332,13 @@ function mongoStorage({
330
332
  dbOptions,
331
333
  collections,
332
334
  persistState: enablePersistence = true,
333
- indexerName = "default"
335
+ indexerName: identifier = "default"
334
336
  }) {
335
337
  return defineIndexerPlugin((indexer) => {
338
+ let indexerId = "";
336
339
  indexer.hooks.hook("run:before", async () => {
340
+ const { indexerName } = useInternalContext();
341
+ indexerId = generateIndexerId(indexerName, identifier);
337
342
  await withTransaction(client, async (session) => {
338
343
  const db = client.db(dbName, dbOptions);
339
344
  if (enablePersistence) {
@@ -350,7 +355,7 @@ function mongoStorage({
350
355
  const { cursor, filter } = await getState({
351
356
  db,
352
357
  session,
353
- indexerName
358
+ indexerId
354
359
  });
355
360
  if (cursor) {
356
361
  request.startingCursor = cursor;
@@ -369,7 +374,7 @@ function mongoStorage({
369
374
  const db = client.db(dbName, dbOptions);
370
375
  await invalidate(db, session, cursor, collections);
371
376
  if (enablePersistence) {
372
- await invalidateState({ db, session, cursor, indexerName });
377
+ await invalidateState({ db, session, cursor, indexerId });
373
378
  }
374
379
  });
375
380
  });
@@ -385,7 +390,7 @@ function mongoStorage({
385
390
  endCursor,
386
391
  session,
387
392
  filter: request.filter[1],
388
- indexerName
393
+ indexerId
389
394
  });
390
395
  }
391
396
  });
@@ -399,7 +404,7 @@ function mongoStorage({
399
404
  const db = client.db(dbName, dbOptions);
400
405
  await finalize(db, session, cursor, collections);
401
406
  if (enablePersistence) {
402
- await finalizeState({ db, session, cursor, indexerName });
407
+ await finalizeState({ db, session, cursor, indexerId });
403
408
  }
404
409
  });
405
410
  });
@@ -412,7 +417,7 @@ function mongoStorage({
412
417
  const db = client.db(dbName, dbOptions);
413
418
  await invalidate(db, session, cursor, collections);
414
419
  if (enablePersistence) {
415
- await invalidateState({ db, session, cursor, indexerName });
420
+ await invalidateState({ db, session, cursor, indexerId });
416
421
  }
417
422
  });
418
423
  });
@@ -428,7 +433,12 @@ function mongoStorage({
428
433
  await next();
429
434
  delete context[MONGO_PROPERTY];
430
435
  if (enablePersistence) {
431
- await persistState({ db, endCursor, session, indexerName });
436
+ await persistState({
437
+ db,
438
+ endCursor,
439
+ session,
440
+ indexerId
441
+ });
432
442
  }
433
443
  });
434
444
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apibara/plugin-mongo",
3
- "version": "2.0.0-beta.37",
3
+ "version": "2.0.0-beta.39",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -35,7 +35,7 @@
35
35
  "mongodb": "^6.12.0"
36
36
  },
37
37
  "dependencies": {
38
- "@apibara/indexer": "2.0.0-beta.37",
39
- "@apibara/protocol": "2.0.0-beta.37"
38
+ "@apibara/indexer": "2.0.0-beta.39",
39
+ "@apibara/protocol": "2.0.0-beta.39"
40
40
  }
41
41
  }
package/src/index.ts CHANGED
@@ -2,6 +2,8 @@ import { useIndexerContext } from "@apibara/indexer";
2
2
  import { defineIndexerPlugin } from "@apibara/indexer/plugins";
3
3
  import type { DbOptions, MongoClient } from "mongodb";
4
4
 
5
+ import { generateIndexerId } from "@apibara/indexer/internal";
6
+ import { useInternalContext } from "@apibara/indexer/internal/plugins";
5
7
  import { finalize, invalidate } from "./mongo";
6
8
  import {
7
9
  finalizeState,
@@ -54,10 +56,15 @@ export function mongoStorage<TFilter, TBlock>({
54
56
  dbOptions,
55
57
  collections,
56
58
  persistState: enablePersistence = true,
57
- indexerName = "default",
59
+ indexerName: identifier = "default",
58
60
  }: MongoStorageOptions) {
59
61
  return defineIndexerPlugin<TFilter, TBlock>((indexer) => {
62
+ let indexerId = "";
63
+
60
64
  indexer.hooks.hook("run:before", async () => {
65
+ const { indexerName } = useInternalContext();
66
+ indexerId = generateIndexerId(indexerName, identifier);
67
+
61
68
  await withTransaction(client, async (session) => {
62
69
  const db = client.db(dbName, dbOptions);
63
70
  if (enablePersistence) {
@@ -76,7 +83,7 @@ export function mongoStorage<TFilter, TBlock>({
76
83
  const { cursor, filter } = await getState<TFilter>({
77
84
  db,
78
85
  session,
79
- indexerName,
86
+ indexerId,
80
87
  });
81
88
 
82
89
  if (cursor) {
@@ -102,7 +109,7 @@ export function mongoStorage<TFilter, TBlock>({
102
109
  await invalidate(db, session, cursor, collections);
103
110
 
104
111
  if (enablePersistence) {
105
- await invalidateState({ db, session, cursor, indexerName });
112
+ await invalidateState({ db, session, cursor, indexerId });
106
113
  }
107
114
  });
108
115
  });
@@ -119,7 +126,7 @@ export function mongoStorage<TFilter, TBlock>({
119
126
  endCursor,
120
127
  session,
121
128
  filter: request.filter[1],
122
- indexerName,
129
+ indexerId,
123
130
  });
124
131
  }
125
132
  });
@@ -137,7 +144,7 @@ export function mongoStorage<TFilter, TBlock>({
137
144
  await finalize(db, session, cursor, collections);
138
145
 
139
146
  if (enablePersistence) {
140
- await finalizeState({ db, session, cursor, indexerName });
147
+ await finalizeState({ db, session, cursor, indexerId });
141
148
  }
142
149
  });
143
150
  });
@@ -154,7 +161,7 @@ export function mongoStorage<TFilter, TBlock>({
154
161
  await invalidate(db, session, cursor, collections);
155
162
 
156
163
  if (enablePersistence) {
157
- await invalidateState({ db, session, cursor, indexerName });
164
+ await invalidateState({ db, session, cursor, indexerId });
158
165
  }
159
166
  });
160
167
  });
@@ -175,7 +182,12 @@ export function mongoStorage<TFilter, TBlock>({
175
182
  delete context[MONGO_PROPERTY];
176
183
 
177
184
  if (enablePersistence) {
178
- await persistState({ db, endCursor, session, indexerName });
185
+ await persistState({
186
+ db,
187
+ endCursor,
188
+ session,
189
+ indexerId,
190
+ });
179
191
  }
180
192
  });
181
193
  });
@@ -38,13 +38,13 @@ export async function persistState<TFilter>(props: {
38
38
  session: ClientSession;
39
39
  endCursor: Cursor;
40
40
  filter?: TFilter;
41
- indexerName: string;
41
+ indexerId: string;
42
42
  }) {
43
- const { db, session, endCursor, filter, indexerName } = props;
43
+ const { db, session, endCursor, filter, indexerId } = props;
44
44
 
45
45
  if (endCursor) {
46
46
  await db.collection<CheckpointSchema>(checkpointCollectionName).updateOne(
47
- { id: indexerName },
47
+ { id: indexerId },
48
48
  {
49
49
  $set: {
50
50
  orderKey: Number(endCursor.orderKey),
@@ -59,7 +59,7 @@ export async function persistState<TFilter>(props: {
59
59
  await db
60
60
  .collection<FilterSchema>(filterCollectionName)
61
61
  .updateMany(
62
- { id: indexerName, toBlock: null },
62
+ { id: indexerId, toBlock: null },
63
63
  { $set: { toBlock: Number(endCursor.orderKey) } },
64
64
  { session },
65
65
  );
@@ -67,7 +67,7 @@ export async function persistState<TFilter>(props: {
67
67
  // Insert new filter
68
68
  await db.collection<FilterSchema>(filterCollectionName).updateOne(
69
69
  {
70
- id: indexerName,
70
+ id: indexerId,
71
71
  fromBlock: Number(endCursor.orderKey),
72
72
  },
73
73
  {
@@ -86,16 +86,16 @@ export async function persistState<TFilter>(props: {
86
86
  export async function getState<TFilter>(props: {
87
87
  db: Db;
88
88
  session: ClientSession;
89
- indexerName: string;
89
+ indexerId: string;
90
90
  }): Promise<{ cursor?: Cursor; filter?: TFilter }> {
91
- const { db, session, indexerName } = props;
91
+ const { db, session, indexerId } = props;
92
92
 
93
93
  let cursor: Cursor | undefined;
94
94
  let filter: TFilter | undefined;
95
95
 
96
96
  const checkpointRow = await db
97
97
  .collection<CheckpointSchema>(checkpointCollectionName)
98
- .findOne({ id: indexerName }, { session });
98
+ .findOne({ id: indexerId }, { session });
99
99
 
100
100
  if (checkpointRow) {
101
101
  cursor = {
@@ -108,7 +108,7 @@ export async function getState<TFilter>(props: {
108
108
  .collection<FilterSchema>(filterCollectionName)
109
109
  .findOne(
110
110
  {
111
- id: indexerName,
111
+ id: indexerId,
112
112
  toBlock: null,
113
113
  },
114
114
  { session },
@@ -125,21 +125,21 @@ export async function invalidateState(props: {
125
125
  db: Db;
126
126
  session: ClientSession;
127
127
  cursor: Cursor;
128
- indexerName: string;
128
+ indexerId: string;
129
129
  }) {
130
- const { db, session, cursor, indexerName } = props;
130
+ const { db, session, cursor, indexerId } = props;
131
131
 
132
132
  await db
133
133
  .collection<FilterSchema>(filterCollectionName)
134
134
  .deleteMany(
135
- { id: indexerName, fromBlock: { $gt: Number(cursor.orderKey) } },
135
+ { id: indexerId, fromBlock: { $gt: Number(cursor.orderKey) } },
136
136
  { session },
137
137
  );
138
138
 
139
139
  await db
140
140
  .collection<FilterSchema>(filterCollectionName)
141
141
  .updateMany(
142
- { id: indexerName, toBlock: { $gt: Number(cursor.orderKey) } },
142
+ { id: indexerId, toBlock: { $gt: Number(cursor.orderKey) } },
143
143
  { $set: { toBlock: null } },
144
144
  { session },
145
145
  );
@@ -149,13 +149,13 @@ export async function finalizeState(props: {
149
149
  db: Db;
150
150
  session: ClientSession;
151
151
  cursor: Cursor;
152
- indexerName: string;
152
+ indexerId: string;
153
153
  }) {
154
- const { db, session, cursor, indexerName } = props;
154
+ const { db, session, cursor, indexerId } = props;
155
155
 
156
156
  await db.collection<FilterSchema>(filterCollectionName).deleteMany(
157
157
  {
158
- id: indexerName,
158
+ id: indexerId,
159
159
  toBlock: { $lte: Number(cursor.orderKey) },
160
160
  },
161
161
  { session },