@myrjfa/state 2.2.0 → 2.3.2

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.
Files changed (117) hide show
  1. package/LICENSE +201 -201
  2. package/README.md +20 -3
  3. package/dist/index.d.ts +8 -0
  4. package/dist/index.d.ts.map +1 -1
  5. package/dist/index.js +8 -0
  6. package/dist/lib/actions/actions.d.ts +13 -13
  7. package/dist/lib/actions/actions.d.ts.map +1 -1
  8. package/dist/lib/actions/actions.js +5 -4
  9. package/dist/lib/actions/auth.d.ts +116 -7
  10. package/dist/lib/actions/auth.d.ts.map +1 -1
  11. package/dist/lib/actions/auth.js +59 -10
  12. package/dist/lib/actions/chat.d.ts +261 -24
  13. package/dist/lib/actions/chat.d.ts.map +1 -1
  14. package/dist/lib/actions/chat.js +525 -41
  15. package/dist/lib/actions/fetcher.d.ts.map +1 -1
  16. package/dist/lib/actions/fetcher.js +26 -9
  17. package/dist/lib/actions/serverActions.d.ts +1 -0
  18. package/dist/lib/actions/serverActions.d.ts.map +1 -1
  19. package/dist/lib/actions/serverActions.js +15 -0
  20. package/dist/lib/actions/socket.d.ts.map +1 -1
  21. package/dist/lib/actions/socket.js +5 -1
  22. package/dist/lib/actions.d.ts +26 -26
  23. package/dist/lib/actions.d.ts.map +1 -1
  24. package/dist/lib/actions.js +17 -12
  25. package/dist/lib/adminDashboardActions.d.ts +15 -3
  26. package/dist/lib/adminDashboardActions.d.ts.map +1 -1
  27. package/dist/lib/adminDashboardActions.js +16 -7
  28. package/dist/lib/authSessionManager.d.ts.map +1 -1
  29. package/dist/lib/authSessionManager.js +77 -12
  30. package/dist/lib/authSessionPolicy.d.ts +44 -0
  31. package/dist/lib/authSessionPolicy.d.ts.map +1 -0
  32. package/dist/lib/authSessionPolicy.js +61 -0
  33. package/dist/lib/authorizationActions.d.ts +77 -0
  34. package/dist/lib/authorizationActions.d.ts.map +1 -0
  35. package/dist/lib/authorizationActions.js +61 -0
  36. package/dist/lib/context/ChatContext.d.ts +25 -6
  37. package/dist/lib/context/ChatContext.d.ts.map +1 -1
  38. package/dist/lib/context/ChatContext.js +356 -245
  39. package/dist/lib/discountActions.d.ts +43 -0
  40. package/dist/lib/discountActions.d.ts.map +1 -0
  41. package/dist/lib/discountActions.js +69 -0
  42. package/dist/lib/loyaltyActions.d.ts +32 -0
  43. package/dist/lib/loyaltyActions.d.ts.map +1 -0
  44. package/dist/lib/loyaltyActions.js +92 -0
  45. package/dist/lib/models/adventure.d.ts +0 -2
  46. package/dist/lib/models/adventure.d.ts.map +1 -1
  47. package/dist/lib/models/authorization.d.ts +108 -0
  48. package/dist/lib/models/authorization.d.ts.map +1 -0
  49. package/dist/lib/models/authorization.js +266 -0
  50. package/dist/lib/models/blog.d.ts +6 -6
  51. package/dist/lib/models/booking.d.ts +7 -2
  52. package/dist/lib/models/booking.d.ts.map +1 -1
  53. package/dist/lib/models/chat.d.ts +418 -32
  54. package/dist/lib/models/chat.d.ts.map +1 -1
  55. package/dist/lib/models/chat.js +5 -1
  56. package/dist/lib/models/discount.d.ts +589 -138
  57. package/dist/lib/models/discount.d.ts.map +1 -1
  58. package/dist/lib/models/discount.js +118 -96
  59. package/dist/lib/models/guide.d.ts +0 -2
  60. package/dist/lib/models/guide.d.ts.map +1 -1
  61. package/dist/lib/models/loyalty.d.ts +88 -0
  62. package/dist/lib/models/loyalty.d.ts.map +1 -0
  63. package/dist/lib/models/loyalty.js +1 -0
  64. package/dist/lib/models/notifications.d.ts +6 -6
  65. package/dist/lib/models/opportunities/freelance.d.ts +66 -20
  66. package/dist/lib/models/opportunities/freelance.d.ts.map +1 -1
  67. package/dist/lib/models/opportunities/internship.d.ts +66 -20
  68. package/dist/lib/models/opportunities/internship.d.ts.map +1 -1
  69. package/dist/lib/models/opportunities/job.d.ts +66 -20
  70. package/dist/lib/models/opportunities/job.d.ts.map +1 -1
  71. package/dist/lib/models/opportunities/opportunity.d.ts +66 -20
  72. package/dist/lib/models/opportunities/opportunity.d.ts.map +1 -1
  73. package/dist/lib/models/opportunities/opportunity.js +2 -0
  74. package/dist/lib/models/opportunities/volunteerJob.d.ts +66 -20
  75. package/dist/lib/models/opportunities/volunteerJob.d.ts.map +1 -1
  76. package/dist/lib/models/package.d.ts +77 -216
  77. package/dist/lib/models/package.d.ts.map +1 -1
  78. package/dist/lib/models/package.js +0 -2
  79. package/dist/lib/models/portfolio.d.ts +2 -2
  80. package/dist/lib/models/pricing.d.ts +12 -12
  81. package/dist/lib/models/props.d.ts +1 -1
  82. package/dist/lib/models/props.d.ts.map +1 -1
  83. package/dist/lib/models/rental.d.ts +0 -2
  84. package/dist/lib/models/rental.d.ts.map +1 -1
  85. package/dist/lib/models/review.d.ts +2 -2
  86. package/dist/lib/models/stay.d.ts +17 -17
  87. package/dist/lib/models/store.d.ts +71 -0
  88. package/dist/lib/models/store.d.ts.map +1 -0
  89. package/dist/lib/models/store.js +1 -0
  90. package/dist/lib/models/tile.d.ts +0 -2
  91. package/dist/lib/models/tile.d.ts.map +1 -1
  92. package/dist/lib/models/travelPackage.d.ts +211 -310
  93. package/dist/lib/models/travelPackage.d.ts.map +1 -1
  94. package/dist/lib/models/travelPackage.js +0 -2
  95. package/dist/lib/models/user.d.ts +32 -8
  96. package/dist/lib/models/user.d.ts.map +1 -1
  97. package/dist/lib/models/user.js +10 -1
  98. package/dist/lib/opportunityFormPage.d.ts +1 -0
  99. package/dist/lib/opportunityFormPage.d.ts.map +1 -1
  100. package/dist/lib/opportunityFormPage.js +1 -0
  101. package/dist/lib/rentalActions.js +0 -1
  102. package/dist/lib/rentalDummyData.d.ts.map +1 -1
  103. package/dist/lib/rentalDummyData.js +0 -35
  104. package/dist/lib/rentalFormPage.d.ts +0 -2
  105. package/dist/lib/rentalFormPage.d.ts.map +1 -1
  106. package/dist/lib/rentalFormPage.js +0 -3
  107. package/dist/lib/storeActions.d.ts +25 -0
  108. package/dist/lib/storeActions.d.ts.map +1 -0
  109. package/dist/lib/storeActions.js +46 -0
  110. package/dist/lib/storeDummyData.d.ts +2 -26
  111. package/dist/lib/storeDummyData.d.ts.map +1 -1
  112. package/dist/lib/userAtom.d.ts +178 -42
  113. package/dist/lib/userAtom.d.ts.map +1 -1
  114. package/dist/lib/userAtom.js +80 -52
  115. package/dist/lib/utils.d.ts.map +1 -1
  116. package/dist/lib/utils.js +1 -1
  117. package/package.json +4 -2
@@ -1,26 +1,31 @@
1
+ import { type AuthSessionStatus } from './authSessionPolicy';
1
2
  export declare const storageInitializedAtom: import("jotai").PrimitiveAtom<boolean> & {
2
3
  init: boolean;
3
4
  };
4
5
  export declare const userAtom: import("jotai").WritableAtom<{
5
- isActive: boolean;
6
- country: string;
7
- rating: number;
8
- ratingCount: number;
9
- reviewCount: number;
10
6
  username: string;
7
+ email: string;
11
8
  firstName: string;
12
9
  lastName: string;
13
- email: string;
14
- password: string;
15
10
  phoneNumber: string;
11
+ password: string;
16
12
  countryCode: string;
13
+ country: string;
17
14
  gender: "male" | "female" | "other";
15
+ rating: number;
16
+ ratingCount: number;
17
+ reviewCount: number;
18
18
  joinedDate: Date;
19
+ isActive: boolean;
19
20
  lastActive: Date;
20
21
  verifiedEmail: boolean;
21
22
  verifiedMobile: boolean;
22
- role: "host" | "admin" | "user" | "hr" | "sales";
23
- id?: string | undefined;
23
+ role: string;
24
+ baseAccountType?: "user" | "host" | undefined;
25
+ legacyRole?: string | undefined;
26
+ staffProfileId?: string | null | undefined;
27
+ accountType?: "user" | "host" | "staff" | undefined;
28
+ _id?: string | undefined;
24
29
  location?: string | undefined;
25
30
  pinCode?: string | undefined;
26
31
  dob?: Date | undefined;
@@ -32,6 +37,9 @@ export declare const userAtom: import("jotai").WritableAtom<{
32
37
  accessToken?: string | undefined;
33
38
  refreshToken?: string | undefined;
34
39
  verifiedIdCard?: boolean | undefined;
40
+ permissions?: string[] | undefined;
41
+ baseUserId?: string | null | undefined;
42
+ baseHostId?: string | null | undefined;
35
43
  socialLinks?: Partial<Record<"instagram" | "linkedin" | "youtube" | "googleBusiness", string>> | undefined;
36
44
  userResume?: string | undefined;
37
45
  skills?: {
@@ -41,6 +49,7 @@ export declare const userAtom: import("jotai").WritableAtom<{
41
49
  wishlist?: string[] | undefined;
42
50
  favBlogs?: string[] | undefined;
43
51
  favPackages?: string[] | undefined;
52
+ id?: string | undefined;
44
53
  selfie?: string | undefined;
45
54
  selfieAction?: string | undefined;
46
55
  jobCount?: number | undefined;
@@ -49,12 +58,12 @@ export declare const userAtom: import("jotai").WritableAtom<{
49
58
  panCard?: string | undefined;
50
59
  verifiedBusiness?: "true" | "false" | "inProgress" | undefined;
51
60
  properties?: {
61
+ country: string;
52
62
  type: string;
53
63
  name: string;
64
+ address: string;
54
65
  city: string;
55
66
  state: string;
56
- country: string;
57
- address: string;
58
67
  pinCode?: string | undefined;
59
68
  registrationNumber?: string | undefined;
60
69
  }[] | undefined;
@@ -64,25 +73,29 @@ export declare const userAtom: import("jotai").WritableAtom<{
64
73
  businessApiVerificationStatus?: "pending" | "verified" | "failed" | undefined;
65
74
  businessVerificationDenialReason?: string | undefined;
66
75
  } | null, [{
67
- isActive: boolean;
68
- country: string;
69
- rating: number;
70
- ratingCount: number;
71
- reviewCount: number;
72
76
  username: string;
77
+ email: string;
73
78
  firstName: string;
74
79
  lastName: string;
75
- email: string;
76
- password: string;
77
80
  phoneNumber: string;
81
+ password: string;
78
82
  countryCode: string;
83
+ country: string;
79
84
  gender: "male" | "female" | "other";
85
+ rating: number;
86
+ ratingCount: number;
87
+ reviewCount: number;
80
88
  joinedDate: Date;
89
+ isActive: boolean;
81
90
  lastActive: Date;
82
91
  verifiedEmail: boolean;
83
92
  verifiedMobile: boolean;
84
- role: "host" | "admin" | "user" | "hr" | "sales";
85
- id?: string | undefined;
93
+ role: string;
94
+ baseAccountType?: "user" | "host" | undefined;
95
+ legacyRole?: string | undefined;
96
+ staffProfileId?: string | null | undefined;
97
+ accountType?: "user" | "host" | "staff" | undefined;
98
+ _id?: string | undefined;
86
99
  location?: string | undefined;
87
100
  pinCode?: string | undefined;
88
101
  dob?: Date | undefined;
@@ -94,6 +107,9 @@ export declare const userAtom: import("jotai").WritableAtom<{
94
107
  accessToken?: string | undefined;
95
108
  refreshToken?: string | undefined;
96
109
  verifiedIdCard?: boolean | undefined;
110
+ permissions?: string[] | undefined;
111
+ baseUserId?: string | null | undefined;
112
+ baseHostId?: string | null | undefined;
97
113
  socialLinks?: Partial<Record<"instagram" | "linkedin" | "youtube" | "googleBusiness", string>> | undefined;
98
114
  userResume?: string | undefined;
99
115
  skills?: {
@@ -103,6 +119,7 @@ export declare const userAtom: import("jotai").WritableAtom<{
103
119
  wishlist?: string[] | undefined;
104
120
  favBlogs?: string[] | undefined;
105
121
  favPackages?: string[] | undefined;
122
+ id?: string | undefined;
106
123
  selfie?: string | undefined;
107
124
  selfieAction?: string | undefined;
108
125
  jobCount?: number | undefined;
@@ -111,12 +128,12 @@ export declare const userAtom: import("jotai").WritableAtom<{
111
128
  panCard?: string | undefined;
112
129
  verifiedBusiness?: "true" | "false" | "inProgress" | undefined;
113
130
  properties?: {
131
+ country: string;
114
132
  type: string;
115
133
  name: string;
134
+ address: string;
116
135
  city: string;
117
136
  state: string;
118
- country: string;
119
- address: string;
120
137
  pinCode?: string | undefined;
121
138
  registrationNumber?: string | undefined;
122
139
  }[] | undefined;
@@ -126,25 +143,29 @@ export declare const userAtom: import("jotai").WritableAtom<{
126
143
  businessApiVerificationStatus?: "pending" | "verified" | "failed" | undefined;
127
144
  businessVerificationDenialReason?: string | undefined;
128
145
  } | typeof import("jotai/utils").RESET | ((prev: {
129
- isActive: boolean;
130
- country: string;
131
- rating: number;
132
- ratingCount: number;
133
- reviewCount: number;
134
146
  username: string;
147
+ email: string;
135
148
  firstName: string;
136
149
  lastName: string;
137
- email: string;
138
- password: string;
139
150
  phoneNumber: string;
151
+ password: string;
140
152
  countryCode: string;
153
+ country: string;
141
154
  gender: "male" | "female" | "other";
155
+ rating: number;
156
+ ratingCount: number;
157
+ reviewCount: number;
142
158
  joinedDate: Date;
159
+ isActive: boolean;
143
160
  lastActive: Date;
144
161
  verifiedEmail: boolean;
145
162
  verifiedMobile: boolean;
146
- role: "host" | "admin" | "user" | "hr" | "sales";
147
- id?: string | undefined;
163
+ role: string;
164
+ baseAccountType?: "user" | "host" | undefined;
165
+ legacyRole?: string | undefined;
166
+ staffProfileId?: string | null | undefined;
167
+ accountType?: "user" | "host" | "staff" | undefined;
168
+ _id?: string | undefined;
148
169
  location?: string | undefined;
149
170
  pinCode?: string | undefined;
150
171
  dob?: Date | undefined;
@@ -156,6 +177,9 @@ export declare const userAtom: import("jotai").WritableAtom<{
156
177
  accessToken?: string | undefined;
157
178
  refreshToken?: string | undefined;
158
179
  verifiedIdCard?: boolean | undefined;
180
+ permissions?: string[] | undefined;
181
+ baseUserId?: string | null | undefined;
182
+ baseHostId?: string | null | undefined;
159
183
  socialLinks?: Partial<Record<"instagram" | "linkedin" | "youtube" | "googleBusiness", string>> | undefined;
160
184
  userResume?: string | undefined;
161
185
  skills?: {
@@ -165,6 +189,7 @@ export declare const userAtom: import("jotai").WritableAtom<{
165
189
  wishlist?: string[] | undefined;
166
190
  favBlogs?: string[] | undefined;
167
191
  favPackages?: string[] | undefined;
192
+ id?: string | undefined;
168
193
  selfie?: string | undefined;
169
194
  selfieAction?: string | undefined;
170
195
  jobCount?: number | undefined;
@@ -173,12 +198,12 @@ export declare const userAtom: import("jotai").WritableAtom<{
173
198
  panCard?: string | undefined;
174
199
  verifiedBusiness?: "true" | "false" | "inProgress" | undefined;
175
200
  properties?: {
201
+ country: string;
176
202
  type: string;
177
203
  name: string;
204
+ address: string;
178
205
  city: string;
179
206
  state: string;
180
- country: string;
181
- address: string;
182
207
  pinCode?: string | undefined;
183
208
  registrationNumber?: string | undefined;
184
209
  }[] | undefined;
@@ -188,25 +213,118 @@ export declare const userAtom: import("jotai").WritableAtom<{
188
213
  businessApiVerificationStatus?: "pending" | "verified" | "failed" | undefined;
189
214
  businessVerificationDenialReason?: string | undefined;
190
215
  } | null) => {
191
- isActive: boolean;
216
+ username: string;
217
+ email: string;
218
+ firstName: string;
219
+ lastName: string;
220
+ phoneNumber: string;
221
+ password: string;
222
+ countryCode: string;
192
223
  country: string;
224
+ gender: "male" | "female" | "other";
193
225
  rating: number;
194
226
  ratingCount: number;
195
227
  reviewCount: number;
228
+ joinedDate: Date;
229
+ isActive: boolean;
230
+ lastActive: Date;
231
+ verifiedEmail: boolean;
232
+ verifiedMobile: boolean;
233
+ role: string;
234
+ baseAccountType?: "user" | "host" | undefined;
235
+ legacyRole?: string | undefined;
236
+ staffProfileId?: string | null | undefined;
237
+ accountType?: "user" | "host" | "staff" | undefined;
238
+ _id?: string | undefined;
239
+ location?: string | undefined;
240
+ pinCode?: string | undefined;
241
+ dob?: Date | undefined;
242
+ profilePic?: string | undefined;
243
+ blogsCount?: number | undefined;
244
+ userBio?: string | undefined;
245
+ userIdCard?: string | undefined;
246
+ watchHistory?: string[] | undefined;
247
+ accessToken?: string | undefined;
248
+ refreshToken?: string | undefined;
249
+ verifiedIdCard?: boolean | undefined;
250
+ permissions?: string[] | undefined;
251
+ baseUserId?: string | null | undefined;
252
+ baseHostId?: string | null | undefined;
253
+ socialLinks?: Partial<Record<"instagram" | "linkedin" | "youtube" | "googleBusiness", string>> | undefined;
254
+ userResume?: string | undefined;
255
+ skills?: {
256
+ skill: string;
257
+ skillExpertise: number;
258
+ }[] | undefined;
259
+ wishlist?: string[] | undefined;
260
+ favBlogs?: string[] | undefined;
261
+ favPackages?: string[] | undefined;
262
+ id?: string | undefined;
263
+ selfie?: string | undefined;
264
+ selfieAction?: string | undefined;
265
+ jobCount?: number | undefined;
266
+ travelPackageCount?: number | undefined;
267
+ gstNumber?: string | undefined;
268
+ panCard?: string | undefined;
269
+ verifiedBusiness?: "true" | "false" | "inProgress" | undefined;
270
+ properties?: {
271
+ country: string;
272
+ type: string;
273
+ name: string;
274
+ address: string;
275
+ city: string;
276
+ state: string;
277
+ pinCode?: string | undefined;
278
+ registrationNumber?: string | undefined;
279
+ }[] | undefined;
280
+ businessDocument?: string | undefined;
281
+ businessIdType?: "PAN" | "GST" | "Udyam" | "PersonalPAN" | undefined;
282
+ businessIdNumber?: string | undefined;
283
+ businessApiVerificationStatus?: "pending" | "verified" | "failed" | undefined;
284
+ businessVerificationDenialReason?: string | undefined;
285
+ } | typeof import("jotai/utils").RESET | null) | null], void>;
286
+ export declare const isLoggedInAtom: import("jotai").WritableAtom<boolean, [boolean | typeof import("jotai/utils").RESET | ((prev: boolean) => boolean | typeof import("jotai/utils").RESET)], void>;
287
+ /**
288
+ * Changes whenever a login/logout boundary occurs.
289
+ *
290
+ * Background session requests capture this value. Responses belonging to an
291
+ * older revision must not clear a newer authenticated state.
292
+ */
293
+ export declare const authRevisionAtom: import("jotai").PrimitiveAtom<number> & {
294
+ init: number;
295
+ };
296
+ export type { AuthSessionStatus } from './authSessionPolicy';
297
+ /** Backend reconciliation state for the currently persisted identity. */
298
+ export declare const authSessionStatusAtom: import("jotai").PrimitiveAtom<AuthSessionStatus> & {
299
+ init: AuthSessionStatus;
300
+ };
301
+ /**
302
+ * Atomically commits a successful login to the active Jotai store.
303
+ */
304
+ export declare const commitLoginAtom: import("jotai").WritableAtom<null, [authenticatedUser: {
196
305
  username: string;
306
+ email: string;
197
307
  firstName: string;
198
308
  lastName: string;
199
- email: string;
200
- password: string;
201
309
  phoneNumber: string;
310
+ password: string;
202
311
  countryCode: string;
312
+ country: string;
203
313
  gender: "male" | "female" | "other";
314
+ rating: number;
315
+ ratingCount: number;
316
+ reviewCount: number;
204
317
  joinedDate: Date;
318
+ isActive: boolean;
205
319
  lastActive: Date;
206
320
  verifiedEmail: boolean;
207
321
  verifiedMobile: boolean;
208
- role: "host" | "admin" | "user" | "hr" | "sales";
209
- id?: string | undefined;
322
+ role: string;
323
+ baseAccountType?: "user" | "host" | undefined;
324
+ legacyRole?: string | undefined;
325
+ staffProfileId?: string | null | undefined;
326
+ accountType?: "user" | "host" | "staff" | undefined;
327
+ _id?: string | undefined;
210
328
  location?: string | undefined;
211
329
  pinCode?: string | undefined;
212
330
  dob?: Date | undefined;
@@ -218,6 +336,9 @@ export declare const userAtom: import("jotai").WritableAtom<{
218
336
  accessToken?: string | undefined;
219
337
  refreshToken?: string | undefined;
220
338
  verifiedIdCard?: boolean | undefined;
339
+ permissions?: string[] | undefined;
340
+ baseUserId?: string | null | undefined;
341
+ baseHostId?: string | null | undefined;
221
342
  socialLinks?: Partial<Record<"instagram" | "linkedin" | "youtube" | "googleBusiness", string>> | undefined;
222
343
  userResume?: string | undefined;
223
344
  skills?: {
@@ -227,6 +348,7 @@ export declare const userAtom: import("jotai").WritableAtom<{
227
348
  wishlist?: string[] | undefined;
228
349
  favBlogs?: string[] | undefined;
229
350
  favPackages?: string[] | undefined;
351
+ id?: string | undefined;
230
352
  selfie?: string | undefined;
231
353
  selfieAction?: string | undefined;
232
354
  jobCount?: number | undefined;
@@ -235,12 +357,12 @@ export declare const userAtom: import("jotai").WritableAtom<{
235
357
  panCard?: string | undefined;
236
358
  verifiedBusiness?: "true" | "false" | "inProgress" | undefined;
237
359
  properties?: {
360
+ country: string;
238
361
  type: string;
239
362
  name: string;
363
+ address: string;
240
364
  city: string;
241
365
  state: string;
242
- country: string;
243
- address: string;
244
366
  pinCode?: string | undefined;
245
367
  registrationNumber?: string | undefined;
246
368
  }[] | undefined;
@@ -249,9 +371,23 @@ export declare const userAtom: import("jotai").WritableAtom<{
249
371
  businessIdNumber?: string | undefined;
250
372
  businessApiVerificationStatus?: "pending" | "verified" | "failed" | undefined;
251
373
  businessVerificationDenialReason?: string | undefined;
252
- } | typeof import("jotai/utils").RESET | null) | null], void>;
253
- export declare const isLoggedInAtom: import("jotai").WritableAtom<boolean, [boolean | typeof import("jotai/utils").RESET | ((prev: boolean) => boolean | typeof import("jotai/utils").RESET)], void>;
374
+ }], void> & {
375
+ init: null;
376
+ };
254
377
  export declare const userLoadingAtom: import("jotai").Atom<boolean>;
378
+ export declare const resetAuthStateAtom: import("jotai").WritableAtom<null, [], void> & {
379
+ init: null;
380
+ };
381
+ /**
382
+ * Clears provisional browser identity while keeping public auth controls
383
+ * disabled until the backend cookie/device cleanup request has settled.
384
+ */
385
+ export declare const beginAuthCleanupAtom: import("jotai").WritableAtom<null, [], void> & {
386
+ init: null;
387
+ };
388
+ export declare const finishAuthCleanupAtom: import("jotai").WritableAtom<null, [expectedRevision: number], void> & {
389
+ init: null;
390
+ };
255
391
  export declare const initializeAuthSessionAtom: import("jotai").WritableAtom<null, [], Promise<void>> & {
256
392
  init: null;
257
393
  };
@@ -1 +1 @@
1
- {"version":3,"file":"userAtom.d.ts","sourceRoot":"","sources":["../../src/lib/userAtom.ts"],"names":[],"mappings":"AA6EA,eAAO,MAAM,sBAAsB;;CAAuB,CAAC;AAW3D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6DAQpB,CAAC;AAEF,eAAO,MAAM,cAAc,iKAA6C,CAAC;AAGzE,eAAO,MAAM,eAAe,+BAM1B,CAAC;AAGH,eAAO,MAAM,yBAAyB;;CA+CrC,CAAC;AAGF,wBAAgB,cAAc,SAS7B"}
1
+ {"version":3,"file":"userAtom.d.ts","sourceRoot":"","sources":["../../src/lib/userAtom.ts"],"names":[],"mappings":"AAMA,OAAO,EAIH,KAAK,iBAAiB,EACzB,MAAM,qBAAqB,CAAC;AA0D7B,eAAO,MAAM,sBAAsB;;CAAuB,CAAC;AAG3D,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6DAQpB,CAAC;AAEF,eAAO,MAAM,cAAc,iKAA6C,CAAC;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;CAAU,CAAC;AAExC,YAAY,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,yEAAyE;AACzE,eAAO,MAAM,qBAAqB;;CAA0C,CAAC;AAE7E;;GAEG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS3B,CAAC;AAGF,eAAO,MAAM,eAAe,+BAS1B,CAAC;AAGH,eAAO,MAAM,kBAAkB;;CAY7B,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;CAU/B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;CAMjC,CAAC;AAGF,eAAO,MAAM,yBAAyB;;CAiCrC,CAAC;AAEF,wBAAgB,cAAc,SAY7B"}
@@ -2,23 +2,14 @@
2
2
  import CryptoJS from 'crypto-js';
3
3
  import { atom, getDefaultStore } from 'jotai';
4
4
  import { atomWithStorage } from 'jotai/utils';
5
- import { getCurrentUser } from './actions/actions';
5
+ import { clearSessionCookies } from './actions/auth';
6
+ import { canFinishAuthCleanup, clearCacheMissSessionBoundary, isAuthSessionPending, } from './authSessionPolicy';
6
7
  const STORAGE_KEY = process.env.NEXT_PUBLIC_USER_KEY;
7
8
  const LOGIN_KEY = process.env.NEXT_PUBLIC_LOGIN_KEY;
8
9
  const SECRET_KEY = process.env.NEXT_PUBLIC_RACE;
9
10
  const EXPIRY_DAYS = 90;
10
11
  const EXPIRY_MS = EXPIRY_DAYS * 24 * 60 * 60 * 1000;
11
- const AUTH_BOOTSTRAP_TIMEOUT_MS = 3000;
12
12
  const store = getDefaultStore();
13
- function withTimeout(promise, timeoutMs) {
14
- let timeoutId;
15
- const timeout = new Promise((_, reject) => {
16
- timeoutId = setTimeout(() => {
17
- reject(new Error('Auth session initialization timed out'));
18
- }, timeoutMs);
19
- });
20
- return Promise.race([promise, timeout]).finally(() => clearTimeout(timeoutId));
21
- }
22
13
  // 🔐 Encryption
23
14
  const encrypt = (data) => CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString();
24
15
  const decrypt = (cipher) => {
@@ -45,14 +36,14 @@ const getWithExpiry = (key) => {
45
36
  return null;
46
37
  const { value, expiry } = data;
47
38
  if (Date.now() > expiry) {
48
- resetAuthState();
39
+ localStorage.removeItem(key);
49
40
  return null;
50
41
  }
51
42
  return value;
52
43
  }
53
44
  catch (e) {
54
45
  console.warn('Invalid user data:', e);
55
- resetAuthState();
46
+ localStorage.removeItem(key);
56
47
  return null;
57
48
  }
58
49
  };
@@ -67,12 +58,6 @@ const setWithExpiry = (key, value) => {
67
58
  };
68
59
  // Storage initialization atom - tracks if we've tried to load from storage
69
60
  export const storageInitializedAtom = atom(false);
70
- storageInitializedAtom.onMount = (setAtom) => {
71
- const timeout = setTimeout(() => {
72
- setAtom(true);
73
- }, AUTH_BOOTSTRAP_TIMEOUT_MS);
74
- return () => clearTimeout(timeout);
75
- };
76
61
  // 🍱 Base storage atom (persisted)
77
62
  export const userAtom = atomWithStorage(STORAGE_KEY, null, {
78
63
  getItem: (key) => getWithExpiry(key),
@@ -80,57 +65,97 @@ export const userAtom = atomWithStorage(STORAGE_KEY, null, {
80
65
  removeItem: (key) => localStorage.removeItem(key),
81
66
  });
82
67
  export const isLoggedInAtom = atomWithStorage(LOGIN_KEY, false);
68
+ /**
69
+ * Changes whenever a login/logout boundary occurs.
70
+ *
71
+ * Background session requests capture this value. Responses belonging to an
72
+ * older revision must not clear a newer authenticated state.
73
+ */
74
+ export const authRevisionAtom = atom(0);
75
+ /** Backend reconciliation state for the currently persisted identity. */
76
+ export const authSessionStatusAtom = atom("initializing");
77
+ /**
78
+ * Atomically commits a successful login to the active Jotai store.
79
+ */
80
+ export const commitLoginAtom = atom(null, (_get, set, authenticatedUser) => {
81
+ set(userAtom, authenticatedUser);
82
+ set(isLoggedInAtom, true);
83
+ set(storageInitializedAtom, true);
84
+ set(authSessionStatusAtom, "authenticated");
85
+ set(authRevisionAtom, (revision) => revision + 1);
86
+ });
83
87
  // 🕒 Tracks if user is loading
84
88
  export const userLoadingAtom = atom((get) => {
85
- // The issue was here - we need to properly track initialization state
86
89
  const initialized = get(storageInitializedAtom);
87
- // We're loading if we haven't initialized storage yet
88
- return !initialized;
90
+ const sessionStatus = get(authSessionStatusAtom);
91
+ // Reconciliation is an authentication boundary, not background cosmetic
92
+ // work. Keep login/register controls unavailable until validation or
93
+ // cookie cleanup settles so a late Set-Cookie response cannot erase a
94
+ // newly-created session.
95
+ return !initialized || isAuthSessionPending(sessionStatus);
96
+ });
97
+ export const resetAuthStateAtom = atom(null, (_get, set) => {
98
+ if (typeof window === "undefined")
99
+ return;
100
+ localStorage.removeItem(STORAGE_KEY);
101
+ localStorage.removeItem(LOGIN_KEY);
102
+ // Update the active Jotai store used by the calling React component.
103
+ set(userAtom, null);
104
+ set(isLoggedInAtom, false);
105
+ set(storageInitializedAtom, true);
106
+ set(authSessionStatusAtom, "signed-out");
107
+ set(authRevisionAtom, (revision) => revision + 1);
108
+ });
109
+ /**
110
+ * Clears provisional browser identity while keeping public auth controls
111
+ * disabled until the backend cookie/device cleanup request has settled.
112
+ */
113
+ export const beginAuthCleanupAtom = atom(null, (_get, set) => {
114
+ if (typeof window === "undefined")
115
+ return;
116
+ localStorage.removeItem(STORAGE_KEY);
117
+ localStorage.removeItem(LOGIN_KEY);
118
+ set(userAtom, null);
119
+ set(isLoggedInAtom, false);
120
+ set(storageInitializedAtom, true);
121
+ set(authSessionStatusAtom, "clearing");
122
+ set(authRevisionAtom, (revision) => revision + 1);
123
+ });
124
+ export const finishAuthCleanupAtom = atom(null, (get, set, expectedRevision) => {
125
+ if (!canFinishAuthCleanup(expectedRevision, get(authRevisionAtom)))
126
+ return;
127
+ set(authSessionStatusAtom, "signed-out");
89
128
  });
90
129
  // Initialize storage atom effect
91
130
  export const initializeAuthSessionAtom = atom(null, async (get, set) => {
92
131
  // Only run in browser
93
132
  if (typeof window === 'undefined')
94
133
  return;
95
- // 1. Validate session (role-aware — host route differs from user route)
96
- // const session = await validateSession();
97
- // if (session.success) {
98
- // Session validated successfully
99
- // } else {
100
- // resetAuthState();
101
- // set(storageInitializedAtom, true);
102
- // return;
103
- // }
104
- // NOTE: if validateSession fails we do NOT reset — we just fall through
105
- // to cache/API. A failed ping could mean the backend is temporarily down,
106
- // the user is a host (different endpoint), etc. We only clear state if we
107
- // POSITIVELY know the user is logged out (getCurrentUser fails).
108
- // 2. Try cache (localStorage)
134
+ // Try the local identity cache first. It remains provisional until the
135
+ // backend confirms that the cookies belong to the same actor.
109
136
  const userData = getWithExpiry(STORAGE_KEY);
110
137
  if (userData) {
111
- set(userAtom, userData);
112
- set(isLoggedInAtom, true);
113
- set(storageInitializedAtom, true);
138
+ set(commitLoginAtom, userData);
139
+ set(authSessionStatusAtom, "validating");
114
140
  return;
115
141
  }
116
- // 3. If cache miss: fetch user from backend using session cookie
142
+ // Missing persisted identity is always a cleanup boundary. The endpoint
143
+ // is idempotent for a fresh guest and revokes stale cookie-only sessions.
144
+ set(beginAuthCleanupAtom);
145
+ const cleanupRevision = get(authRevisionAtom);
117
146
  try {
118
- // This endpoint can hit DB or another cache as needed
119
- const remoteUser = await withTimeout(getCurrentUser(), AUTH_BOOTSTRAP_TIMEOUT_MS);
120
- if (remoteUser) {
121
- set(userAtom, remoteUser);
122
- set(isLoggedInAtom, true);
123
- setWithExpiry(STORAGE_KEY, remoteUser); // Write to local cache for next time
124
- }
125
- else {
126
- resetAuthState();
127
- }
147
+ await clearCacheMissSessionBoundary({
148
+ cleanupRevision,
149
+ getCurrentRevision: () => get(authRevisionAtom),
150
+ clearSession: clearSessionCookies,
151
+ });
128
152
  }
129
153
  catch {
130
- resetAuthState();
154
+ // clearSessionCookies is bounded. Local signed-out state is still
155
+ // published only after the cleanup attempt has settled.
131
156
  }
132
157
  finally {
133
- set(storageInitializedAtom, true);
158
+ set(finishAuthCleanupAtom, cleanupRevision);
134
159
  }
135
160
  });
136
161
  export function resetAuthState() {
@@ -142,4 +167,7 @@ export function resetAuthState() {
142
167
  localStorage.removeItem(LOGIN_KEY);
143
168
  store.set(userAtom, null);
144
169
  store.set(isLoggedInAtom, false);
170
+ store.set(storageInitializedAtom, true);
171
+ store.set(authSessionStatusAtom, "signed-out");
172
+ store.set(authRevisionAtom, (revision) => revision + 1);
145
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,MAAM,CAAC;AAG7C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,eAAO,MAAM,UAAU,UAA2C,CAAC;AAEnE,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,GAAG,SAAS,WAGjD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAG9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBrD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWvD;AAGD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,WACO,CAAC;AAEhE,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,WAKrC,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,MAAM,MAAM,WACE,CAAC;AAE3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAcjE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAM5D;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,IAAI,WAczC,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,UAItE;AAGD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,WAAW,EACX,IAAI,GACL,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;;;;;;;;;;;;;;;;;;;;;;EA8BA;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAaxD;AAED,eAAO,MAAM,eAAe,UAA0D,CAAC;AAEvF,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,CAanD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,UAAU,EAAQ,MAAM,MAAM,CAAC;AAG7C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,eAAO,MAAM,eAAe,KAAK,CAAC;AAElC,eAAO,MAAM,UAAU,UAA4E,CAAC;AAEpG,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGtD;AAED,eAAO,MAAM,UAAU,GAAI,KAAK,MAAM,GAAG,SAAS,WAGjD,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAGtD;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAG9D;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBrD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWvD;AAGD,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,WACO,CAAC;AAEhE,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,WAKrC,CAAA;AAED,eAAO,MAAM,WAAW,GAAI,OAAO,MAAM,EAAE,SAAS,MAAM,EAAE,MAAM,MAAM,WACE,CAAC;AAE3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAcjE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAM5D;AAED,eAAO,MAAM,eAAe,GAAI,MAAM,IAAI,WAczC,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAM,UAItE;AAGD,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,WAAW,EACX,IAAI,GACL,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;;;;;;;;;;;;;;;;;;;;;;;EA8BA;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAaxD;AAED,eAAO,MAAM,eAAe,UAA0D,CAAC;AAEvF,wBAAgB,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,GAAG,MAAM,EAAE,CAanD"}
package/dist/lib/utils.js CHANGED
@@ -5,7 +5,7 @@ import he from "he";
5
5
  import { twMerge } from "tailwind-merge";
6
6
  export const MAX_IMAGE_SIZE_MB = 5;
7
7
  export const MAX_PDF_SIZE_MB = 10;
8
- export const validRoles = ["host", "user", "admin", "hr", "sales"];
8
+ export const validRoles = ["host", "user", "admin", "hr", "sales", "developer", "customer_support"];
9
9
  export function cn(...inputs) {
10
10
  return twMerge(clsx(inputs));
11
11
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myrjfa/state",
3
- "version": "2.2.0",
3
+ "version": "2.3.2",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./dist/*": "./dist/*.js"
@@ -55,6 +55,8 @@
55
55
  "license": "MIT",
56
56
  "scripts": {
57
57
  "build": "tsc",
58
- "dev": "tsc --watch"
58
+ "dev": "tsc --watch",
59
+ "test:authorization": "node --test tests/authorization.test.mjs",
60
+ "test:auth-session": "node --experimental-strip-types --test tests/authSessionPolicy.test.mjs"
59
61
  }
60
62
  }