entity-client 1.0.24 → 1.0.25
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/EntityAppServerApi.d.ts +33 -0
- package/dist/EntityServerApi.d.ts +16 -0
- package/dist/client/base.d.ts +11 -0
- package/dist/client/base.js +1 -1
- package/dist/client/base.js.map +3 -3
- package/dist/client/request.js +1 -1
- package/dist/client/request.js.map +3 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +3 -3
- package/dist/mixins/app/plugins/alimtalk.d.ts +2 -0
- package/dist/mixins/app/plugins/friendtalk.d.ts +2 -0
- package/dist/mixins/app/plugins/holidays.d.ts +2 -0
- package/dist/mixins/app/plugins/identity.d.ts +2 -0
- package/dist/mixins/app/plugins/llm.d.ts +2 -0
- package/dist/mixins/app/plugins/ocr.d.ts +2 -0
- package/dist/mixins/app/plugins/pg.d.ts +2 -0
- package/dist/mixins/app/plugins/push.d.ts +2 -0
- package/dist/mixins/app/plugins/sms.d.ts +2 -0
- package/dist/mixins/app/plugins/taxinvoice.d.ts +2 -0
- package/dist/mixins/app/routes/account.d.ts +2 -0
- package/dist/mixins/app/routes/board.d.ts +3 -0
- package/dist/mixins/app/routes/board.js +1 -1
- package/dist/mixins/app/routes/board.js.map +2 -2
- package/dist/mixins/app/routes/email-verify.d.ts +2 -0
- package/dist/mixins/app/routes/oauth.d.ts +2 -0
- package/dist/mixins/app/routes/password-reset.d.ts +2 -0
- package/dist/mixins/app/routes/two-factor.d.ts +2 -0
- package/dist/mixins/server/admin.d.ts +2 -0
- package/dist/mixins/server/auth.d.ts +2 -0
- package/dist/mixins/server/auth.js +1 -1
- package/dist/mixins/server/auth.js.map +3 -3
- package/dist/mixins/server/entity.d.ts +2 -0
- package/dist/mixins/server/file.d.ts +2 -0
- package/dist/mixins/server/push.d.ts +2 -0
- package/dist/mixins/server/smtp.d.ts +2 -0
- package/dist/mixins/server/transaction.d.ts +2 -0
- package/dist/mixins/server/utils.d.ts +2 -0
- package/dist/react.js +1 -1
- package/dist/react.js.map +3 -3
- package/package.json +1 -1
|
@@ -17,6 +17,7 @@ declare const EntityAppServerApi_base: {
|
|
|
17
17
|
csrfRefresher: (() => Promise<void>) | null;
|
|
18
18
|
requestAbortControllers: Map<string, AbortController>;
|
|
19
19
|
activeTxId: string | null;
|
|
20
|
+
initialHealthFired: boolean;
|
|
20
21
|
keepSession: boolean;
|
|
21
22
|
refreshBuffer: number;
|
|
22
23
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -39,6 +40,7 @@ declare const EntityAppServerApi_base: {
|
|
|
39
40
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
40
41
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
41
42
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
43
|
+
fireInitialHealth(): void;
|
|
42
44
|
setToken(token: string): void;
|
|
43
45
|
setAccessTokenFromResponse(token: string): void;
|
|
44
46
|
syncRealtimeWithToken(): void;
|
|
@@ -103,6 +105,7 @@ declare const EntityAppServerApi_base: {
|
|
|
103
105
|
csrfRefresher: (() => Promise<void>) | null;
|
|
104
106
|
requestAbortControllers: Map<string, AbortController>;
|
|
105
107
|
activeTxId: string | null;
|
|
108
|
+
initialHealthFired: boolean;
|
|
106
109
|
keepSession: boolean;
|
|
107
110
|
refreshBuffer: number;
|
|
108
111
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -125,6 +128,7 @@ declare const EntityAppServerApi_base: {
|
|
|
125
128
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
126
129
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
127
130
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
131
|
+
fireInitialHealth(): void;
|
|
128
132
|
setToken(token: string): void;
|
|
129
133
|
setAccessTokenFromResponse(token: string): void;
|
|
130
134
|
syncRealtimeWithToken(): void;
|
|
@@ -192,6 +196,7 @@ declare const EntityAppServerApi_base: {
|
|
|
192
196
|
csrfRefresher: (() => Promise<void>) | null;
|
|
193
197
|
requestAbortControllers: Map<string, AbortController>;
|
|
194
198
|
activeTxId: string | null;
|
|
199
|
+
initialHealthFired: boolean;
|
|
195
200
|
keepSession: boolean;
|
|
196
201
|
refreshBuffer: number;
|
|
197
202
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -214,6 +219,7 @@ declare const EntityAppServerApi_base: {
|
|
|
214
219
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
215
220
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
216
221
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
222
|
+
fireInitialHealth(): void;
|
|
217
223
|
setToken(token: string): void;
|
|
218
224
|
setAccessTokenFromResponse(token: string): void;
|
|
219
225
|
syncRealtimeWithToken(): void;
|
|
@@ -282,6 +288,7 @@ declare const EntityAppServerApi_base: {
|
|
|
282
288
|
csrfRefresher: (() => Promise<void>) | null;
|
|
283
289
|
requestAbortControllers: Map<string, AbortController>;
|
|
284
290
|
activeTxId: string | null;
|
|
291
|
+
initialHealthFired: boolean;
|
|
285
292
|
keepSession: boolean;
|
|
286
293
|
refreshBuffer: number;
|
|
287
294
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -304,6 +311,7 @@ declare const EntityAppServerApi_base: {
|
|
|
304
311
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
305
312
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
306
313
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
314
|
+
fireInitialHealth(): void;
|
|
307
315
|
setToken(token: string): void;
|
|
308
316
|
setAccessTokenFromResponse(token: string): void;
|
|
309
317
|
syncRealtimeWithToken(): void;
|
|
@@ -374,6 +382,7 @@ declare const EntityAppServerApi_base: {
|
|
|
374
382
|
csrfRefresher: (() => Promise<void>) | null;
|
|
375
383
|
requestAbortControllers: Map<string, AbortController>;
|
|
376
384
|
activeTxId: string | null;
|
|
385
|
+
initialHealthFired: boolean;
|
|
377
386
|
keepSession: boolean;
|
|
378
387
|
refreshBuffer: number;
|
|
379
388
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -396,6 +405,7 @@ declare const EntityAppServerApi_base: {
|
|
|
396
405
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
397
406
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
398
407
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
408
|
+
fireInitialHealth(): void;
|
|
399
409
|
setToken(token: string): void;
|
|
400
410
|
setAccessTokenFromResponse(token: string): void;
|
|
401
411
|
syncRealtimeWithToken(): void;
|
|
@@ -465,6 +475,7 @@ declare const EntityAppServerApi_base: {
|
|
|
465
475
|
csrfRefresher: (() => Promise<void>) | null;
|
|
466
476
|
requestAbortControllers: Map<string, AbortController>;
|
|
467
477
|
activeTxId: string | null;
|
|
478
|
+
initialHealthFired: boolean;
|
|
468
479
|
keepSession: boolean;
|
|
469
480
|
refreshBuffer: number;
|
|
470
481
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -487,6 +498,7 @@ declare const EntityAppServerApi_base: {
|
|
|
487
498
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
488
499
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
489
500
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
501
|
+
fireInitialHealth(): void;
|
|
490
502
|
setToken(token: string): void;
|
|
491
503
|
setAccessTokenFromResponse(token: string): void;
|
|
492
504
|
syncRealtimeWithToken(): void;
|
|
@@ -558,6 +570,7 @@ declare const EntityAppServerApi_base: {
|
|
|
558
570
|
csrfRefresher: (() => Promise<void>) | null;
|
|
559
571
|
requestAbortControllers: Map<string, AbortController>;
|
|
560
572
|
activeTxId: string | null;
|
|
573
|
+
initialHealthFired: boolean;
|
|
561
574
|
keepSession: boolean;
|
|
562
575
|
refreshBuffer: number;
|
|
563
576
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -580,6 +593,7 @@ declare const EntityAppServerApi_base: {
|
|
|
580
593
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
581
594
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
582
595
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
596
|
+
fireInitialHealth(): void;
|
|
583
597
|
setToken(token: string): void;
|
|
584
598
|
setAccessTokenFromResponse(token: string): void;
|
|
585
599
|
syncRealtimeWithToken(): void;
|
|
@@ -678,6 +692,7 @@ declare const EntityAppServerApi_base: {
|
|
|
678
692
|
csrfRefresher: (() => Promise<void>) | null;
|
|
679
693
|
requestAbortControllers: Map<string, AbortController>;
|
|
680
694
|
activeTxId: string | null;
|
|
695
|
+
initialHealthFired: boolean;
|
|
681
696
|
keepSession: boolean;
|
|
682
697
|
refreshBuffer: number;
|
|
683
698
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -700,6 +715,7 @@ declare const EntityAppServerApi_base: {
|
|
|
700
715
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
701
716
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
702
717
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
718
|
+
fireInitialHealth(): void;
|
|
703
719
|
setToken(token: string): void;
|
|
704
720
|
setAccessTokenFromResponse(token: string): void;
|
|
705
721
|
syncRealtimeWithToken(): void;
|
|
@@ -767,6 +783,7 @@ declare const EntityAppServerApi_base: {
|
|
|
767
783
|
csrfRefresher: (() => Promise<void>) | null;
|
|
768
784
|
requestAbortControllers: Map<string, AbortController>;
|
|
769
785
|
activeTxId: string | null;
|
|
786
|
+
initialHealthFired: boolean;
|
|
770
787
|
keepSession: boolean;
|
|
771
788
|
refreshBuffer: number;
|
|
772
789
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -789,6 +806,7 @@ declare const EntityAppServerApi_base: {
|
|
|
789
806
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
790
807
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
791
808
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
809
|
+
fireInitialHealth(): void;
|
|
792
810
|
setToken(token: string): void;
|
|
793
811
|
setAccessTokenFromResponse(token: string): void;
|
|
794
812
|
syncRealtimeWithToken(): void;
|
|
@@ -859,6 +877,7 @@ declare const EntityAppServerApi_base: {
|
|
|
859
877
|
csrfRefresher: (() => Promise<void>) | null;
|
|
860
878
|
requestAbortControllers: Map<string, AbortController>;
|
|
861
879
|
activeTxId: string | null;
|
|
880
|
+
initialHealthFired: boolean;
|
|
862
881
|
keepSession: boolean;
|
|
863
882
|
refreshBuffer: number;
|
|
864
883
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -881,6 +900,7 @@ declare const EntityAppServerApi_base: {
|
|
|
881
900
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
882
901
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
883
902
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
903
|
+
fireInitialHealth(): void;
|
|
884
904
|
setToken(token: string): void;
|
|
885
905
|
setAccessTokenFromResponse(token: string): void;
|
|
886
906
|
syncRealtimeWithToken(): void;
|
|
@@ -950,6 +970,7 @@ declare const EntityAppServerApi_base: {
|
|
|
950
970
|
csrfRefresher: (() => Promise<void>) | null;
|
|
951
971
|
requestAbortControllers: Map<string, AbortController>;
|
|
952
972
|
activeTxId: string | null;
|
|
973
|
+
initialHealthFired: boolean;
|
|
953
974
|
keepSession: boolean;
|
|
954
975
|
refreshBuffer: number;
|
|
955
976
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -972,6 +993,7 @@ declare const EntityAppServerApi_base: {
|
|
|
972
993
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
973
994
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
974
995
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
996
|
+
fireInitialHealth(): void;
|
|
975
997
|
setToken(token: string): void;
|
|
976
998
|
setAccessTokenFromResponse(token: string): void;
|
|
977
999
|
syncRealtimeWithToken(): void;
|
|
@@ -1042,6 +1064,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1042
1064
|
csrfRefresher: (() => Promise<void>) | null;
|
|
1043
1065
|
requestAbortControllers: Map<string, AbortController>;
|
|
1044
1066
|
activeTxId: string | null;
|
|
1067
|
+
initialHealthFired: boolean;
|
|
1045
1068
|
keepSession: boolean;
|
|
1046
1069
|
refreshBuffer: number;
|
|
1047
1070
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -1064,6 +1087,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1064
1087
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
1065
1088
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
1066
1089
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
1090
|
+
fireInitialHealth(): void;
|
|
1067
1091
|
setToken(token: string): void;
|
|
1068
1092
|
setAccessTokenFromResponse(token: string): void;
|
|
1069
1093
|
syncRealtimeWithToken(): void;
|
|
@@ -1132,6 +1156,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1132
1156
|
csrfRefresher: (() => Promise<void>) | null;
|
|
1133
1157
|
requestAbortControllers: Map<string, AbortController>;
|
|
1134
1158
|
activeTxId: string | null;
|
|
1159
|
+
initialHealthFired: boolean;
|
|
1135
1160
|
keepSession: boolean;
|
|
1136
1161
|
refreshBuffer: number;
|
|
1137
1162
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -1154,6 +1179,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1154
1179
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
1155
1180
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
1156
1181
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
1182
|
+
fireInitialHealth(): void;
|
|
1157
1183
|
setToken(token: string): void;
|
|
1158
1184
|
setAccessTokenFromResponse(token: string): void;
|
|
1159
1185
|
syncRealtimeWithToken(): void;
|
|
@@ -1222,6 +1248,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1222
1248
|
csrfRefresher: (() => Promise<void>) | null;
|
|
1223
1249
|
requestAbortControllers: Map<string, AbortController>;
|
|
1224
1250
|
activeTxId: string | null;
|
|
1251
|
+
initialHealthFired: boolean;
|
|
1225
1252
|
keepSession: boolean;
|
|
1226
1253
|
refreshBuffer: number;
|
|
1227
1254
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -1244,6 +1271,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1244
1271
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
1245
1272
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
1246
1273
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
1274
|
+
fireInitialHealth(): void;
|
|
1247
1275
|
setToken(token: string): void;
|
|
1248
1276
|
setAccessTokenFromResponse(token: string): void;
|
|
1249
1277
|
syncRealtimeWithToken(): void;
|
|
@@ -1304,6 +1332,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1304
1332
|
getBoardPost<T = unknown>(seq: number): Promise<T>;
|
|
1305
1333
|
createBoardPost<T = unknown>(category: string, body: Record<string, unknown>): Promise<T>;
|
|
1306
1334
|
updateBoardPost<T = unknown>(seq: number, body: Record<string, unknown>): Promise<T>;
|
|
1335
|
+
expireBoardPost<T = unknown>(seq: number): Promise<T>;
|
|
1307
1336
|
deleteBoardPost<T = unknown>(seq: number): Promise<T>;
|
|
1308
1337
|
listBoardComments<T = unknown>(postSeq: number, query?: Record<string, unknown>): Promise<T>;
|
|
1309
1338
|
createBoardComment<T = unknown>(postSeq: number, body: Record<string, unknown>): Promise<T>;
|
|
@@ -1340,6 +1369,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1340
1369
|
csrfRefresher: (() => Promise<void>) | null;
|
|
1341
1370
|
requestAbortControllers: Map<string, AbortController>;
|
|
1342
1371
|
activeTxId: string | null;
|
|
1372
|
+
initialHealthFired: boolean;
|
|
1343
1373
|
keepSession: boolean;
|
|
1344
1374
|
refreshBuffer: number;
|
|
1345
1375
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -1362,6 +1392,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1362
1392
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
1363
1393
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
1364
1394
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
1395
|
+
fireInitialHealth(): void;
|
|
1365
1396
|
setToken(token: string): void;
|
|
1366
1397
|
setAccessTokenFromResponse(token: string): void;
|
|
1367
1398
|
syncRealtimeWithToken(): void;
|
|
@@ -1435,6 +1466,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1435
1466
|
csrfRefresher: (() => Promise<void>) | null;
|
|
1436
1467
|
requestAbortControllers: Map<string, AbortController>;
|
|
1437
1468
|
activeTxId: string | null;
|
|
1469
|
+
initialHealthFired: boolean;
|
|
1438
1470
|
keepSession: boolean;
|
|
1439
1471
|
refreshBuffer: number;
|
|
1440
1472
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -1457,6 +1489,7 @@ declare const EntityAppServerApi_base: {
|
|
|
1457
1489
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
1458
1490
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
1459
1491
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
1492
|
+
fireInitialHealth(): void;
|
|
1460
1493
|
setToken(token: string): void;
|
|
1461
1494
|
setAccessTokenFromResponse(token: string): void;
|
|
1462
1495
|
syncRealtimeWithToken(): void;
|
|
@@ -48,6 +48,7 @@ declare const EntityServerApi_base: {
|
|
|
48
48
|
csrfRefresher: (() => Promise<void>) | null;
|
|
49
49
|
requestAbortControllers: Map<string, AbortController>;
|
|
50
50
|
activeTxId: string | null;
|
|
51
|
+
initialHealthFired: boolean;
|
|
51
52
|
keepSession: boolean;
|
|
52
53
|
refreshBuffer: number;
|
|
53
54
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -70,6 +71,7 @@ declare const EntityServerApi_base: {
|
|
|
70
71
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
71
72
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
72
73
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
74
|
+
fireInitialHealth(): void;
|
|
73
75
|
setToken(token: string): void;
|
|
74
76
|
setAccessTokenFromResponse(token: string): void;
|
|
75
77
|
syncRealtimeWithToken(): void;
|
|
@@ -136,6 +138,7 @@ declare const EntityServerApi_base: {
|
|
|
136
138
|
csrfRefresher: (() => Promise<void>) | null;
|
|
137
139
|
requestAbortControllers: Map<string, AbortController>;
|
|
138
140
|
activeTxId: string | null;
|
|
141
|
+
initialHealthFired: boolean;
|
|
139
142
|
keepSession: boolean;
|
|
140
143
|
refreshBuffer: number;
|
|
141
144
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -158,6 +161,7 @@ declare const EntityServerApi_base: {
|
|
|
158
161
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
159
162
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
160
163
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
164
|
+
fireInitialHealth(): void;
|
|
161
165
|
setToken(token: string): void;
|
|
162
166
|
setAccessTokenFromResponse(token: string): void;
|
|
163
167
|
syncRealtimeWithToken(): void;
|
|
@@ -286,6 +290,7 @@ declare const EntityServerApi_base: {
|
|
|
286
290
|
csrfRefresher: (() => Promise<void>) | null;
|
|
287
291
|
requestAbortControllers: Map<string, AbortController>;
|
|
288
292
|
activeTxId: string | null;
|
|
293
|
+
initialHealthFired: boolean;
|
|
289
294
|
keepSession: boolean;
|
|
290
295
|
refreshBuffer: number;
|
|
291
296
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -308,6 +313,7 @@ declare const EntityServerApi_base: {
|
|
|
308
313
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
309
314
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
310
315
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
316
|
+
fireInitialHealth(): void;
|
|
311
317
|
setToken(token: string): void;
|
|
312
318
|
setAccessTokenFromResponse(token: string): void;
|
|
313
319
|
syncRealtimeWithToken(): void;
|
|
@@ -380,6 +386,7 @@ declare const EntityServerApi_base: {
|
|
|
380
386
|
csrfRefresher: (() => Promise<void>) | null;
|
|
381
387
|
requestAbortControllers: Map<string, AbortController>;
|
|
382
388
|
activeTxId: string | null;
|
|
389
|
+
initialHealthFired: boolean;
|
|
383
390
|
keepSession: boolean;
|
|
384
391
|
refreshBuffer: number;
|
|
385
392
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -402,6 +409,7 @@ declare const EntityServerApi_base: {
|
|
|
402
409
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
403
410
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
404
411
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
412
|
+
fireInitialHealth(): void;
|
|
405
413
|
setToken(token: string): void;
|
|
406
414
|
setAccessTokenFromResponse(token: string): void;
|
|
407
415
|
syncRealtimeWithToken(): void;
|
|
@@ -492,6 +500,7 @@ declare const EntityServerApi_base: {
|
|
|
492
500
|
csrfRefresher: (() => Promise<void>) | null;
|
|
493
501
|
requestAbortControllers: Map<string, AbortController>;
|
|
494
502
|
activeTxId: string | null;
|
|
503
|
+
initialHealthFired: boolean;
|
|
495
504
|
keepSession: boolean;
|
|
496
505
|
refreshBuffer: number;
|
|
497
506
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -514,6 +523,7 @@ declare const EntityServerApi_base: {
|
|
|
514
523
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
515
524
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
516
525
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
526
|
+
fireInitialHealth(): void;
|
|
517
527
|
setToken(token: string): void;
|
|
518
528
|
setAccessTokenFromResponse(token: string): void;
|
|
519
529
|
syncRealtimeWithToken(): void;
|
|
@@ -639,6 +649,7 @@ declare const EntityServerApi_base: {
|
|
|
639
649
|
csrfRefresher: (() => Promise<void>) | null;
|
|
640
650
|
requestAbortControllers: Map<string, AbortController>;
|
|
641
651
|
activeTxId: string | null;
|
|
652
|
+
initialHealthFired: boolean;
|
|
642
653
|
keepSession: boolean;
|
|
643
654
|
refreshBuffer: number;
|
|
644
655
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -661,6 +672,7 @@ declare const EntityServerApi_base: {
|
|
|
661
672
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
662
673
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
663
674
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
675
|
+
fireInitialHealth(): void;
|
|
664
676
|
setToken(token: string): void;
|
|
665
677
|
setAccessTokenFromResponse(token: string): void;
|
|
666
678
|
syncRealtimeWithToken(): void;
|
|
@@ -790,6 +802,7 @@ declare const EntityServerApi_base: {
|
|
|
790
802
|
csrfRefresher: (() => Promise<void>) | null;
|
|
791
803
|
requestAbortControllers: Map<string, AbortController>;
|
|
792
804
|
activeTxId: string | null;
|
|
805
|
+
initialHealthFired: boolean;
|
|
793
806
|
keepSession: boolean;
|
|
794
807
|
refreshBuffer: number;
|
|
795
808
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -812,6 +825,7 @@ declare const EntityServerApi_base: {
|
|
|
812
825
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
813
826
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
814
827
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
828
|
+
fireInitialHealth(): void;
|
|
815
829
|
setToken(token: string): void;
|
|
816
830
|
setAccessTokenFromResponse(token: string): void;
|
|
817
831
|
syncRealtimeWithToken(): void;
|
|
@@ -909,6 +923,7 @@ declare const EntityServerApi_base: {
|
|
|
909
923
|
csrfCookieName: string;
|
|
910
924
|
requestAbortControllers: Map<string, AbortController>;
|
|
911
925
|
activeTxId: string | null;
|
|
926
|
+
initialHealthFired: boolean;
|
|
912
927
|
keepSession: boolean;
|
|
913
928
|
refreshBuffer: number;
|
|
914
929
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -931,6 +946,7 @@ declare const EntityServerApi_base: {
|
|
|
931
946
|
realtimeStatusListeners: Set<import("./types.js").RealtimeStatusListener>;
|
|
932
947
|
realtimeEventListeners: Map<string, Set<import("./types.js").RealtimeMessageListener>>;
|
|
933
948
|
configure(options: Partial<import("./types.js").EntityServerClientOptions>): void;
|
|
949
|
+
fireInitialHealth(): void;
|
|
934
950
|
setToken(token: string): void;
|
|
935
951
|
syncRealtimeWithToken(): void;
|
|
936
952
|
setAnonymousPacketToken(token: string): void;
|
package/dist/client/base.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export declare class EntityServerClientBase {
|
|
|
15
15
|
csrfRefresher: (() => Promise<void>) | null;
|
|
16
16
|
requestAbortControllers: Map<string, AbortController>;
|
|
17
17
|
activeTxId: string | null;
|
|
18
|
+
/** @internal 브라우저에서 첫 구성 시 health 1회 자동 호출했는지 여부 */
|
|
19
|
+
initialHealthFired: boolean;
|
|
18
20
|
keepSession: boolean;
|
|
19
21
|
refreshBuffer: number;
|
|
20
22
|
onTokenRefreshed?: (accessToken: string, expiresIn: number) => void;
|
|
@@ -45,6 +47,15 @@ export declare class EntityServerClientBase {
|
|
|
45
47
|
constructor(options?: EntityServerClientOptions);
|
|
46
48
|
/** baseUrl, token, encryptRequests 값을 런타임에 갱신합니다. */
|
|
47
49
|
configure(options: Partial<EntityServerClientOptions>): void;
|
|
50
|
+
/**
|
|
51
|
+
* 브라우저에서 클라이언트가 처음 구성될 때 `/v1/health` 를 1회 자동 호출한다.
|
|
52
|
+
*
|
|
53
|
+
* CSRF·anon 쿠키 발급과 패킷 암호화 협상(`X-Packet-Encryption`)을 앱 진입 즉시 선반영해,
|
|
54
|
+
* 프런트 라우트(`/login` 등)와 무관하게 항상 health 가 최소 1회 돌도록 보장한다.
|
|
55
|
+
*
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
fireInitialHealth(): void;
|
|
48
59
|
/** 인증 요청에 사용할 JWT Access Token을 설정합니다. */
|
|
49
60
|
setToken(token: string): void;
|
|
50
61
|
/** 응답 헤더로 받은 access token 갱신을 반영한다. */
|
package/dist/client/base.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{readEnv as m}from"./utils.js";import{derivePacketKey as u,parseRequestBody as f}from"./packet.js";import{entityRequest as l}from"./request.js";const c="/v1/realtime";class y{baseUrl;token;anonymousPacketToken;apiKey;hmacSecret;encryptRequests;csrfEnabled;csrfHeaderName;csrfCookieName;csrfRefresher=null;requestAbortControllers=new Map;activeTxId=null;keepSession;refreshBuffer;onTokenRefreshed;onSessionExpired;onHealthChange;sessionRefreshToken=null;refreshTimer=null;healthTickTimer=null;healthTickPromise=null;realtimeEnabled;realtimePath;realtimeAutoReconnect;realtimeReconnectDelayMs;realtimeStatus;realtimeSocket=null;realtimeConnectPromise=null;realtimeReconnectTimer=null;realtimeShouldReconnect=!1;realtimeMessageListeners=new Set;realtimeStatusListeners=new Set;realtimeEventListeners=new Map;constructor(e={}){const t=m("VITE_ENTITY_SERVER_URL");this.baseUrl=(e.baseUrl??t??"").replace(/\/$/,""),this.token=e.token??"",this.anonymousPacketToken=e.anonymousPacketToken??"",this.apiKey=e.apiKey??"",this.hmacSecret=e.hmacSecret??"",this.encryptRequests=e.encryptRequests??!1,this.csrfEnabled=e.csrfEnabled??!1,this.csrfHeaderName=e.csrfHeaderName??"x-csrf-token",this.csrfCookieName=e.csrfCookieName??"_csrf",this.keepSession=e.keepSession??!1,this.refreshBuffer=e.refreshBuffer??60,this.onTokenRefreshed=e.onTokenRefreshed,this.onSessionExpired=e.onSessionExpired,this.onHealthChange=e.onHealthChange,this.realtimeEnabled=!1,this.realtimePath=c,this.realtimeAutoReconnect=!0,this.realtimeReconnectDelayMs=3e3,this.realtimeStatus="idle",this.applyRealtimeOptions(e.realtime),typeof e.healthTickInterval=="number"&&e.healthTickInterval>0&&Promise.resolve().then(()=>this.startHealthTick(e.healthTickInterval,!1))}configure(e){typeof e.baseUrl=="string"&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),typeof e.token=="string"&&(this.token=e.token),typeof e.anonymousPacketToken=="string"&&(this.anonymousPacketToken=e.anonymousPacketToken),typeof e.encryptRequests=="boolean"&&(this.encryptRequests=e.encryptRequests),typeof e.csrfEnabled=="boolean"&&(this.csrfEnabled=e.csrfEnabled),typeof e.csrfHeaderName=="string"&&(this.csrfHeaderName=e.csrfHeaderName),typeof e.csrfCookieName=="string"&&(this.csrfCookieName=e.csrfCookieName),typeof e.apiKey=="string"&&(this.apiKey=e.apiKey),typeof e.hmacSecret=="string"&&(this.hmacSecret=e.hmacSecret),typeof e.keepSession=="boolean"&&(this.keepSession=e.keepSession),typeof e.refreshBuffer=="number"&&(this.refreshBuffer=e.refreshBuffer),e.onTokenRefreshed&&(this.onTokenRefreshed=e.onTokenRefreshed),e.onSessionExpired&&(this.onSessionExpired=e.onSessionExpired),e.onHealthChange&&(this.onHealthChange=e.onHealthChange),typeof e.realtime<"u"&&this.applyRealtimeOptions(e.realtime),typeof e.healthTickInterval=="number"&&e.healthTickInterval>0&&Promise.resolve().then(()=>this.startHealthTick(e.healthTickInterval,!1))}setToken(e){this.token=e,this.syncRealtimeWithToken()}setAccessTokenFromResponse(e){this.token=e,this.syncRealtimeWithToken()}syncRealtimeWithToken(){if(!this.token){this.disconnectRealtime("token_cleared");return}!this.realtimeEnabled||typeof WebSocket>"u"||this.connectRealtime().catch(()=>{})}setAnonymousPacketToken(e){this.anonymousPacketToken=e}setApiKey(e){this.apiKey=e}setHmacSecret(e){this.hmacSecret=e}setEncryptRequests(e){this.encryptRequests=e}setCsrfEnabled(e){this.csrfEnabled=e}addRealtimeListener(e){this.realtimeMessageListeners.add(e)}removeRealtimeListener(e){this.realtimeMessageListeners.delete(e)}addRealtimeStatusListener(e){this.realtimeStatusListeners.add(e)}removeRealtimeStatusListener(e){this.realtimeStatusListeners.delete(e)}addRealtimeEventListener(e,t){const i=String(e).trim();i&&(this.realtimeEventListeners.has(i)||this.realtimeEventListeners.set(i,new Set),this.realtimeEventListeners.get(i).add(t))}removeRealtimeEventListener(e,t){const i=String(e).trim();if(!i)return;const s=this.realtimeEventListeners.get(i);s&&(s.delete(t),s.size===0&&this.realtimeEventListeners.delete(i))}async connectRealtime(){if(!this.realtimeEnabled){this.setRealtimeStatus("disabled","realtime_disabled");return}if(!this.token)throw new Error("Cannot open realtime connection without access token.");if(typeof WebSocket>"u")throw new Error("WebSocket is not available in this environment.");if(this.realtimeSocket&&this.realtimeSocket.readyState===WebSocket.OPEN)return;if(this.realtimeSocket&&this.realtimeSocket.readyState===WebSocket.CONNECTING&&this.realtimeConnectPromise)return this.realtimeConnectPromise;this.clearRealtimeReconnectTimer(),this.realtimeShouldReconnect=this.realtimeAutoReconnect,this.setRealtimeStatus("connecting","connect_requested");const e=new WebSocket(this.buildRealtimeUrl());return this.realtimeSocket=e,this.realtimeConnectPromise=new Promise((t,i)=>{let s=!1;const r=()=>{s||(s=!0,this.realtimeConnectPromise=null,t())},n=a=>{s||(s=!0,this.realtimeConnectPromise=null,i(a))};e.addEventListener("open",()=>{this.setRealtimeStatus("open","socket_open"),r()}),e.addEventListener("message",a=>{this.handleRealtimeMessage(a.data)}),e.addEventListener("error",()=>{this.setRealtimeStatus("closed","socket_error",new Error("Realtime socket error."))}),e.addEventListener("close",a=>{this.realtimeSocket===e&&(this.realtimeSocket=null);const o=a.reason||"socket_closed",h=new Error(`Realtime socket closed (${a.code}${a.reason?`: ${a.reason}`:""}).`);this.setRealtimeStatus("closed",o,h),s||n(h),this.realtimeShouldReconnect&&this.realtimeEnabled&&this.realtimeAutoReconnect&&this.token&&this.scheduleRealtimeReconnect(o)})}),this.realtimeConnectPromise}disconnectRealtime(e="client_disconnect"){if(this.realtimeShouldReconnect=!1,this.clearRealtimeReconnectTimer(),this.realtimeSocket){const t=this.realtimeSocket;this.realtimeSocket=null;try{(t.readyState===WebSocket.OPEN||t.readyState===WebSocket.CONNECTING)&&t.close(1e3,e)}catch{}}this.realtimeConnectPromise=null,this.setRealtimeStatus(this.realtimeEnabled?"idle":"disabled",e)}sendRealtime(e){return!this.realtimeSocket||this.realtimeSocket.readyState!==WebSocket.OPEN?!1:(this.realtimeSocket.send(JSON.stringify(e)),!0)}subscribeRealtime(e){return this.sendRealtime({type:"subscribe",channel:"session",event:"session.subscribe",data:{subscriptions:e}})}unsubscribeRealtime(e){return this.sendRealtime({type:"unsubscribe",channel:"session",event:"session.unsubscribe",data:{subscriptions:e}})}startHealthTick(e=300*1e3,t=!0){this.stopHealthTick();const i=()=>{this.healthTickPromise||(this.healthTickPromise=(this.csrfRefresher?this.csrfRefresher():Promise.resolve()).then(()=>{this.onHealthChange?.(!0)}).catch(()=>{this.onHealthChange?.(!1)}).finally(()=>{this.healthTickPromise=null}))};t&&i(),this.healthTickTimer=setInterval(i,e)}stopHealthTick(){this.healthTickTimer!==null&&(clearInterval(this.healthTickTimer),this.healthTickTimer=null),this.healthTickPromise=null}scheduleKeepSession(e,t,i){this.clearRefreshTimer(),this.sessionRefreshToken=e;const s=Math.max((t-this.refreshBuffer)*1e3,0);this.refreshTimer=setTimeout(async()=>{if(this.sessionRefreshToken)try{const r=await i(this.sessionRefreshToken);this.onTokenRefreshed?.(r.access_token,r.expires_in),this.scheduleKeepSession(this.sessionRefreshToken,r.expires_in,i)}catch(r){this.clearRefreshTimer(),this.onSessionExpired?.(r instanceof Error?r:new Error(String(r)))}},s)}clearRefreshTimer(){this.refreshTimer!==null&&(clearTimeout(this.refreshTimer),this.refreshTimer=null)}stopKeepSession(){this.clearRefreshTimer(),this.sessionRefreshToken=null}applyRealtimeOptions(e){const t=typeof e=="boolean"?{enabled:e}:e??{};if(this.realtimeEnabled=t.enabled??!1,this.realtimePath=String(t.path??c).trim()||c,this.realtimeAutoReconnect=t.autoReconnect??!0,this.realtimeReconnectDelayMs=Math.max(250,t.reconnectDelayMs??3e3),!this.realtimeEnabled){this.disconnectRealtime("realtime_disabled");return}this.setRealtimeStatus("idle","realtime_enabled")}buildRealtimeUrl(){const e=this.baseUrl||m("VITE_ENTITY_SERVER_URL")||"",t=typeof window<"u"?window.location.origin:"",i=e||t;if(!i)throw new Error("Realtime connection requires baseUrl.");const s=new URL(i,t||void 0),r=s.pathname==="/"?"":s.pathname.replace(/\/+$/,""),n=`/${this.realtimePath.replace(/^\/+/,"")}`;return s.pathname=`${r}${n}`||n,s.search="",s.hash="",s.protocol=s.protocol==="https:"?"wss:":"ws:",s.searchParams.set("access_token",this.token),s.toString()}handleRealtimeMessage(e){if(typeof e!="string")return;let t;try{t=JSON.parse(e)}catch{return}for(const s of this.realtimeMessageListeners)s(t);const i=this.realtimeEventListeners.get(t.event);if(i)for(const s of i)s(t)}scheduleRealtimeReconnect(e){this.clearRealtimeReconnectTimer(),this.realtimeReconnectTimer=setTimeout(()=>{this.realtimeReconnectTimer=null,!(!this.realtimeEnabled||!this.token)&&(this.setRealtimeStatus("connecting",`${e}:reconnect`),this.connectRealtime().catch(()=>{}))},this.realtimeReconnectDelayMs)}clearRealtimeReconnectTimer(){this.realtimeReconnectTimer!==null&&(clearTimeout(this.realtimeReconnectTimer),this.realtimeReconnectTimer=null)}setRealtimeStatus(e,t,i){const s=this.realtimeStatus;if(!(s===e&&typeof t>"u"&&typeof i>"u")){this.realtimeStatus=e;for(const r of this.realtimeStatusListeners)r({status:e,previousStatus:s,...t?{reason:t}:{},...i?{error:i}:{}})}}applyCsrfHealth(){if(!(typeof document>"u")){for(const e of document.cookie.split(";")){const t=e.indexOf("=");if(!(t<0)&&e.substring(0,t).trim()===this.csrfCookieName){this.csrfEnabled=!!e.substring(t+1).trim();return}}this.csrfEnabled=!1}}readRequestBody(e,t="application/json",i=!1){const s=u(this.hmacSecret,this.token||this.anonymousPacketToken);return f(e,t,i,s)}get reqOpts(){return{baseUrl:this.baseUrl,token:this.token,anonymousPacketToken:this.anonymousPacketToken,apiKey:this.apiKey,hmacSecret:this.hmacSecret,encryptRequests:this.encryptRequests,csrfEnabled:this.csrfEnabled,csrfHeaderName:this.csrfHeaderName,csrfCookieName:this.csrfCookieName,refreshCsrfCookie:this.csrfEnabled?this.csrfRefresher:null,requestAbortControllers:this.requestAbortControllers,onAccessToken:e=>{this.setAccessTokenFromResponse(e)}}}prepareRequest(e){return Promise.resolve()}get http(){const e=this;return{get(t,i=!0,s,r){return e.prepareRequest(i).then(()=>l(e.reqOpts,"GET",t,void 0,i,s,r??!0))},post(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"POST",t,i,s,r,n??!0))},put(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"PUT",t,i,s,r,n??!0))},patch(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"PATCH",t,i,s,r,n??!0))},delete(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"DELETE",t,i,s,r,n??!0))}}}request(e,t,i,s=!0,r,n){return this.prepareRequest(s).then(()=>l(this.reqOpts,e,t,i,s,r,n??!0))}async requestBinary(e,t,i,s=!0){await this.prepareRequest(s);const r={"Content-Type":"application/json"};s&&this.token&&(r.Authorization=`Bearer ${this.token}`),this.apiKey&&(r["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+t,{method:e,headers:r,...i!=null?{body:JSON.stringify(i)}:{},credentials:"include"});if(!n.ok){const a=await n.text(),o=new Error(`HTTP ${n.status}: ${a}`);throw o.status=n.status,o}return n.arrayBuffer()}async requestForm(e,t,i,s=!0){const r={};s&&this.token&&(r.Authorization=`Bearer ${this.token}`),this.apiKey&&(r["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+t,{method:e,headers:r,body:i,credentials:"include"}),a=await n.json();if(!a.ok){const o=new Error(a.message??`EntityServer error (HTTP ${n.status})`);throw o.status=n.status,o}return a}async requestFormBinary(e,t,i,s=!0){const r={};s&&this.token&&(r.Authorization=`Bearer ${this.token}`),this.apiKey&&(r["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+t,{method:e,headers:r,body:i,credentials:"include"});if(!n.ok){const a=await n.text(),o=new Error(`HTTP ${n.status}: ${a}`);throw o.status=n.status,o}return n.arrayBuffer()}}export{y as EntityServerClientBase};
|
|
1
|
+
import{readEnv as m}from"./utils.js";import{derivePacketKey as u,parseRequestBody as f}from"./packet.js";import{entityRequest as l}from"./request.js";const c="/v1/realtime";class y{baseUrl;token;anonymousPacketToken;apiKey;hmacSecret;encryptRequests;csrfEnabled;csrfHeaderName;csrfCookieName;csrfRefresher=null;requestAbortControllers=new Map;activeTxId=null;initialHealthFired=!1;keepSession;refreshBuffer;onTokenRefreshed;onSessionExpired;onHealthChange;sessionRefreshToken=null;refreshTimer=null;healthTickTimer=null;healthTickPromise=null;realtimeEnabled;realtimePath;realtimeAutoReconnect;realtimeReconnectDelayMs;realtimeStatus;realtimeSocket=null;realtimeConnectPromise=null;realtimeReconnectTimer=null;realtimeShouldReconnect=!1;realtimeMessageListeners=new Set;realtimeStatusListeners=new Set;realtimeEventListeners=new Map;constructor(e={}){const t=m("VITE_ENTITY_SERVER_URL");this.baseUrl=(e.baseUrl??t??"").replace(/\/$/,""),this.token=e.token??"",this.anonymousPacketToken=e.anonymousPacketToken??"",this.apiKey=e.apiKey??"",this.hmacSecret=e.hmacSecret??"",this.encryptRequests=e.encryptRequests??!1,this.csrfEnabled=e.csrfEnabled??!1,this.csrfHeaderName=e.csrfHeaderName??"x-csrf-token",this.csrfCookieName=e.csrfCookieName??"_csrf",this.keepSession=e.keepSession??!1,this.refreshBuffer=e.refreshBuffer??60,this.onTokenRefreshed=e.onTokenRefreshed,this.onSessionExpired=e.onSessionExpired,this.onHealthChange=e.onHealthChange,this.realtimeEnabled=!1,this.realtimePath=c,this.realtimeAutoReconnect=!0,this.realtimeReconnectDelayMs=3e3,this.realtimeStatus="idle",this.applyRealtimeOptions(e.realtime),typeof e.healthTickInterval=="number"&&e.healthTickInterval>0&&Promise.resolve().then(()=>this.startHealthTick(e.healthTickInterval,!1)),this.fireInitialHealth()}configure(e){typeof e.baseUrl=="string"&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),typeof e.token=="string"&&(this.token=e.token),typeof e.anonymousPacketToken=="string"&&(this.anonymousPacketToken=e.anonymousPacketToken),typeof e.encryptRequests=="boolean"&&(this.encryptRequests=e.encryptRequests),typeof e.csrfEnabled=="boolean"&&(this.csrfEnabled=e.csrfEnabled),typeof e.csrfHeaderName=="string"&&(this.csrfHeaderName=e.csrfHeaderName),typeof e.csrfCookieName=="string"&&(this.csrfCookieName=e.csrfCookieName),typeof e.apiKey=="string"&&(this.apiKey=e.apiKey),typeof e.hmacSecret=="string"&&(this.hmacSecret=e.hmacSecret),typeof e.keepSession=="boolean"&&(this.keepSession=e.keepSession),typeof e.refreshBuffer=="number"&&(this.refreshBuffer=e.refreshBuffer),e.onTokenRefreshed&&(this.onTokenRefreshed=e.onTokenRefreshed),e.onSessionExpired&&(this.onSessionExpired=e.onSessionExpired),e.onHealthChange&&(this.onHealthChange=e.onHealthChange),typeof e.realtime<"u"&&this.applyRealtimeOptions(e.realtime),typeof e.healthTickInterval=="number"&&e.healthTickInterval>0&&Promise.resolve().then(()=>this.startHealthTick(e.healthTickInterval,!1)),this.fireInitialHealth()}fireInitialHealth(){if(this.initialHealthFired||typeof document>"u"||!this.baseUrl)return;this.initialHealthFired=!0;const e=this;typeof e.checkHealth=="function"&&Promise.resolve().then(()=>e.checkHealth(!1).catch(()=>{}))}setToken(e){this.token=e,this.syncRealtimeWithToken()}setAccessTokenFromResponse(e){this.token=e,this.syncRealtimeWithToken()}syncRealtimeWithToken(){if(!this.token){this.disconnectRealtime("token_cleared");return}!this.realtimeEnabled||typeof WebSocket>"u"||this.connectRealtime().catch(()=>{})}setAnonymousPacketToken(e){this.anonymousPacketToken=e}setApiKey(e){this.apiKey=e}setHmacSecret(e){this.hmacSecret=e}setEncryptRequests(e){this.encryptRequests=e}setCsrfEnabled(e){this.csrfEnabled=e}addRealtimeListener(e){this.realtimeMessageListeners.add(e)}removeRealtimeListener(e){this.realtimeMessageListeners.delete(e)}addRealtimeStatusListener(e){this.realtimeStatusListeners.add(e)}removeRealtimeStatusListener(e){this.realtimeStatusListeners.delete(e)}addRealtimeEventListener(e,t){const i=String(e).trim();i&&(this.realtimeEventListeners.has(i)||this.realtimeEventListeners.set(i,new Set),this.realtimeEventListeners.get(i).add(t))}removeRealtimeEventListener(e,t){const i=String(e).trim();if(!i)return;const s=this.realtimeEventListeners.get(i);s&&(s.delete(t),s.size===0&&this.realtimeEventListeners.delete(i))}async connectRealtime(){if(!this.realtimeEnabled){this.setRealtimeStatus("disabled","realtime_disabled");return}if(!this.token)throw new Error("Cannot open realtime connection without access token.");if(typeof WebSocket>"u")throw new Error("WebSocket is not available in this environment.");if(this.realtimeSocket&&this.realtimeSocket.readyState===WebSocket.OPEN)return;if(this.realtimeSocket&&this.realtimeSocket.readyState===WebSocket.CONNECTING&&this.realtimeConnectPromise)return this.realtimeConnectPromise;this.clearRealtimeReconnectTimer(),this.realtimeShouldReconnect=this.realtimeAutoReconnect,this.setRealtimeStatus("connecting","connect_requested");const e=new WebSocket(this.buildRealtimeUrl());return this.realtimeSocket=e,this.realtimeConnectPromise=new Promise((t,i)=>{let s=!1;const r=()=>{s||(s=!0,this.realtimeConnectPromise=null,t())},n=a=>{s||(s=!0,this.realtimeConnectPromise=null,i(a))};e.addEventListener("open",()=>{this.setRealtimeStatus("open","socket_open"),r()}),e.addEventListener("message",a=>{this.handleRealtimeMessage(a.data)}),e.addEventListener("error",()=>{this.setRealtimeStatus("closed","socket_error",new Error("Realtime socket error."))}),e.addEventListener("close",a=>{this.realtimeSocket===e&&(this.realtimeSocket=null);const o=a.reason||"socket_closed",h=new Error(`Realtime socket closed (${a.code}${a.reason?`: ${a.reason}`:""}).`);this.setRealtimeStatus("closed",o,h),s||n(h),this.realtimeShouldReconnect&&this.realtimeEnabled&&this.realtimeAutoReconnect&&this.token&&this.scheduleRealtimeReconnect(o)})}),this.realtimeConnectPromise}disconnectRealtime(e="client_disconnect"){if(this.realtimeShouldReconnect=!1,this.clearRealtimeReconnectTimer(),this.realtimeSocket){const t=this.realtimeSocket;this.realtimeSocket=null;try{(t.readyState===WebSocket.OPEN||t.readyState===WebSocket.CONNECTING)&&t.close(1e3,e)}catch{}}this.realtimeConnectPromise=null,this.setRealtimeStatus(this.realtimeEnabled?"idle":"disabled",e)}sendRealtime(e){return!this.realtimeSocket||this.realtimeSocket.readyState!==WebSocket.OPEN?!1:(this.realtimeSocket.send(JSON.stringify(e)),!0)}subscribeRealtime(e){return this.sendRealtime({type:"subscribe",channel:"session",event:"session.subscribe",data:{subscriptions:e}})}unsubscribeRealtime(e){return this.sendRealtime({type:"unsubscribe",channel:"session",event:"session.unsubscribe",data:{subscriptions:e}})}startHealthTick(e=300*1e3,t=!0){this.stopHealthTick();const i=()=>{this.healthTickPromise||(this.healthTickPromise=(this.csrfRefresher?this.csrfRefresher():Promise.resolve()).then(()=>{this.onHealthChange?.(!0)}).catch(()=>{this.onHealthChange?.(!1)}).finally(()=>{this.healthTickPromise=null}))};t&&i(),this.healthTickTimer=setInterval(i,e)}stopHealthTick(){this.healthTickTimer!==null&&(clearInterval(this.healthTickTimer),this.healthTickTimer=null),this.healthTickPromise=null}scheduleKeepSession(e,t,i){this.clearRefreshTimer(),this.sessionRefreshToken=e;const s=Math.max((t-this.refreshBuffer)*1e3,0);this.refreshTimer=setTimeout(async()=>{if(this.sessionRefreshToken)try{const r=await i(this.sessionRefreshToken);this.onTokenRefreshed?.(r.access_token,r.expires_in),this.scheduleKeepSession(this.sessionRefreshToken,r.expires_in,i)}catch(r){this.clearRefreshTimer(),this.onSessionExpired?.(r instanceof Error?r:new Error(String(r)))}},s)}clearRefreshTimer(){this.refreshTimer!==null&&(clearTimeout(this.refreshTimer),this.refreshTimer=null)}stopKeepSession(){this.clearRefreshTimer(),this.sessionRefreshToken=null}applyRealtimeOptions(e){const t=typeof e=="boolean"?{enabled:e}:e??{};if(this.realtimeEnabled=t.enabled??!1,this.realtimePath=String(t.path??c).trim()||c,this.realtimeAutoReconnect=t.autoReconnect??!0,this.realtimeReconnectDelayMs=Math.max(250,t.reconnectDelayMs??3e3),!this.realtimeEnabled){this.disconnectRealtime("realtime_disabled");return}this.setRealtimeStatus("idle","realtime_enabled")}buildRealtimeUrl(){const e=this.baseUrl||m("VITE_ENTITY_SERVER_URL")||"",t=typeof window<"u"?window.location.origin:"",i=e||t;if(!i)throw new Error("Realtime connection requires baseUrl.");const s=new URL(i,t||void 0),r=s.pathname==="/"?"":s.pathname.replace(/\/+$/,""),n=`/${this.realtimePath.replace(/^\/+/,"")}`;return s.pathname=`${r}${n}`||n,s.search="",s.hash="",s.protocol=s.protocol==="https:"?"wss:":"ws:",s.searchParams.set("access_token",this.token),s.toString()}handleRealtimeMessage(e){if(typeof e!="string")return;let t;try{t=JSON.parse(e)}catch{return}for(const s of this.realtimeMessageListeners)s(t);const i=this.realtimeEventListeners.get(t.event);if(i)for(const s of i)s(t)}scheduleRealtimeReconnect(e){this.clearRealtimeReconnectTimer(),this.realtimeReconnectTimer=setTimeout(()=>{this.realtimeReconnectTimer=null,!(!this.realtimeEnabled||!this.token)&&(this.setRealtimeStatus("connecting",`${e}:reconnect`),this.connectRealtime().catch(()=>{}))},this.realtimeReconnectDelayMs)}clearRealtimeReconnectTimer(){this.realtimeReconnectTimer!==null&&(clearTimeout(this.realtimeReconnectTimer),this.realtimeReconnectTimer=null)}setRealtimeStatus(e,t,i){const s=this.realtimeStatus;if(!(s===e&&typeof t>"u"&&typeof i>"u")){this.realtimeStatus=e;for(const r of this.realtimeStatusListeners)r({status:e,previousStatus:s,...t?{reason:t}:{},...i?{error:i}:{}})}}applyCsrfHealth(){if(!(typeof document>"u")){for(const e of document.cookie.split(";")){const t=e.indexOf("=");if(!(t<0)&&e.substring(0,t).trim()===this.csrfCookieName){this.csrfEnabled=!!e.substring(t+1).trim();return}}this.csrfEnabled=!1}}readRequestBody(e,t="application/json",i=!1){const s=u(this.hmacSecret,this.token||this.anonymousPacketToken);return f(e,t,i,s)}get reqOpts(){return{baseUrl:this.baseUrl,token:this.token,anonymousPacketToken:this.anonymousPacketToken,apiKey:this.apiKey,hmacSecret:this.hmacSecret,encryptRequests:this.encryptRequests,csrfEnabled:this.csrfEnabled,csrfHeaderName:this.csrfHeaderName,csrfCookieName:this.csrfCookieName,refreshCsrfCookie:this.csrfEnabled?this.csrfRefresher:null,requestAbortControllers:this.requestAbortControllers,onAccessToken:e=>{this.setAccessTokenFromResponse(e)}}}prepareRequest(e){return Promise.resolve()}get http(){const e=this;return{get(t,i=!0,s,r){return e.prepareRequest(i).then(()=>l(e.reqOpts,"GET",t,void 0,i,s,r??!0))},post(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"POST",t,i,s,r,n??!0))},put(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"PUT",t,i,s,r,n??!0))},patch(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"PATCH",t,i,s,r,n??!0))},delete(t,i,s=!0,r,n){return e.prepareRequest(s).then(()=>l(e.reqOpts,"DELETE",t,i,s,r,n??!0))}}}request(e,t,i,s=!0,r,n){return this.prepareRequest(s).then(()=>l(this.reqOpts,e,t,i,s,r,n??!0))}async requestBinary(e,t,i,s=!0){await this.prepareRequest(s);const r={"Content-Type":"application/json"};s&&this.token&&(r.Authorization=`Bearer ${this.token}`),this.apiKey&&(r["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+t,{method:e,headers:r,...i!=null?{body:JSON.stringify(i)}:{},credentials:"include"});if(!n.ok){const a=await n.text(),o=new Error(`HTTP ${n.status}: ${a}`);throw o.status=n.status,o}return n.arrayBuffer()}async requestForm(e,t,i,s=!0){const r={};s&&this.token&&(r.Authorization=`Bearer ${this.token}`),this.apiKey&&(r["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+t,{method:e,headers:r,body:i,credentials:"include"}),a=await n.json();if(!a.ok){const o=new Error(a.message??`EntityServer error (HTTP ${n.status})`);throw o.status=n.status,o}return a}async requestFormBinary(e,t,i,s=!0){const r={};s&&this.token&&(r.Authorization=`Bearer ${this.token}`),this.apiKey&&(r["X-API-Key"]=this.apiKey);const n=await fetch(this.baseUrl+t,{method:e,headers:r,body:i,credentials:"include"});if(!n.ok){const a=await n.text(),o=new Error(`HTTP ${n.status}: ${a}`);throw o.status=n.status,o}return n.arrayBuffer()}}export{y as EntityServerClientBase};
|
|
2
2
|
//# sourceMappingURL=base.js.map
|