@shaunlwm/pickle.ts 1.10.0 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as socket_io_client from 'socket.io-client';
2
1
  import { Socket, ManagerOptions, SocketOptions } from 'socket.io-client';
3
2
  import { EventEmitter } from 'node:events';
4
3
 
@@ -50,6 +49,55 @@ type QueueUpdate = {
50
49
  queueLength: number;
51
50
  };
52
51
 
52
+ type ClientLifecyclePhase = "transport_connecting" | "queueing" | "authenticating" | "joining_session" | "awaiting_initial_state" | "ready" | "disconnecting" | "disconnected";
53
+ type ClientLifecycleUpdate = {
54
+ phase: ClientLifecyclePhase;
55
+ occurredAt: number;
56
+ queue?: QueueUpdate;
57
+ };
58
+ type ClientOperationOptions = {
59
+ signal?: AbortSignal;
60
+ timeoutMs?: number;
61
+ };
62
+ type ClientConnectionTimeouts = {
63
+ loginMs: number;
64
+ transportMs: number;
65
+ /** Maximum silence between queue updates, not total time spent queued. */
66
+ queueMs: number;
67
+ authenticationMs: number;
68
+ initialStateMs: number;
69
+ requestMs: number;
70
+ };
71
+ declare const DEFAULT_CLIENT_CONNECTION_TIMEOUTS: {
72
+ readonly loginMs: 20000;
73
+ readonly transportMs: 20000;
74
+ readonly queueMs: 300000;
75
+ readonly authenticationMs: 20000;
76
+ readonly initialStateMs: 15000;
77
+ readonly requestMs: 15000;
78
+ };
79
+ type ClientDisconnectInfo = {
80
+ intentional: boolean;
81
+ reason: string | null;
82
+ occurredAt: number;
83
+ };
84
+
85
+ type ClientOperationErrorCategory = "login_timeout" | "login_rejected" | "invalid_credentials" | "account_banned" | "queue_timeout" | "transport_error" | "auth_timeout" | "auth_failed" | "initial_state_timeout" | "operation_timeout" | "unsupported_operation" | "aborted" | "disconnected" | "kicked" | "server_error";
86
+ type ClientOperationErrorOptions = {
87
+ category: ClientOperationErrorCategory;
88
+ phase: ClientLifecyclePhase;
89
+ retryable: boolean;
90
+ message: string;
91
+ cause?: unknown;
92
+ };
93
+ declare function sanitizeClientErrorMessage(message: string): string;
94
+ declare class ClientOperationError extends Error {
95
+ readonly category: ClientOperationErrorCategory;
96
+ readonly phase: ClientLifecyclePhase;
97
+ readonly retryable: boolean;
98
+ constructor(options: ClientOperationErrorOptions);
99
+ }
100
+
53
101
  /** Core appearance slots shared by all servers (CPJourney, CPLegacy, NewCP). */
54
102
  type PlayerAppearance = {
55
103
  color: number;
@@ -102,7 +150,24 @@ type RoomUser = PlayerAppearance & {
102
150
  x: number;
103
151
  y: number;
104
152
  frame: number;
105
- /** Adapter-specific extras. See each adapter's normalizeUser for keys. */
153
+ /**
154
+ * Adapter-specific extras. See each adapter's normalizeUser for keys.
155
+ *
156
+ * **CPJourney** overlay appearance slots (number):
157
+ * `hat`, `face_mask`, `neck_scarf`, `body_shirt`, `hand_glove`
158
+ *
159
+ * **CPJourney** user state:
160
+ * `transform` (number) — costume ID, 0 = none
161
+ * `walkingPuffleType` (number | null) — puffle species
162
+ * `openSprite` (string | null) — sprite state e.g. "1_3"
163
+ * `mascotGiveaway` (number | null) — non-null = mascot, value = giveaway item ID
164
+ * `iglooOpen` (number) — 0/1
165
+ * `iglooBounds` (number) — 0/1
166
+ * `igloo_slot` (number) — active igloo slot
167
+ * `currentLayer` (number) — rendering layer
168
+ * `fireRank` (number) — fire ninja rank 0–5
169
+ * `isInvisible` (boolean) — mascot visibility flag
170
+ */
106
171
  meta: Record<string, unknown>;
107
172
  /** Original unnormalized server response */
108
173
  _raw: Record<string, unknown>;
@@ -144,7 +209,78 @@ type Postcard = {
144
209
  senderId: number;
145
210
  postcardId: number;
146
211
  extra: string | null;
147
- date: string;
212
+ /** CPJourney MessagePack decodes this as a Date; other adapters may use strings. */
213
+ date: Date | string;
214
+ };
215
+ /** A puffle summary, optionally including CPJourney's full care state. */
216
+ type Puffle = {
217
+ id: number;
218
+ type: number;
219
+ userId?: number;
220
+ name?: string;
221
+ energy?: number;
222
+ health?: number;
223
+ rest?: number;
224
+ experience?: number;
225
+ level?: number;
226
+ adoption_date?: Record<string, unknown>;
227
+ last_feed?: Record<string, unknown>;
228
+ last_slept?: Record<string, unknown>;
229
+ postcard_hungry?: boolean;
230
+ dead?: number;
231
+ ran_away?: number;
232
+ last_dig?: number;
233
+ in_backyard?: number;
234
+ backyard_supplies?: number;
235
+ walking?: boolean;
236
+ backyard?: boolean;
237
+ };
238
+ /** CPJourney puffle care values returned by get_wellbeing/update_wellbeing. */
239
+ type PuffleWellbeing = {
240
+ puffleId: number;
241
+ energy: number;
242
+ health: number;
243
+ rest: number;
244
+ name: string;
245
+ type: number;
246
+ level: number;
247
+ experience: number;
248
+ inBackyard?: number;
249
+ backyardSupplyCost?: number;
250
+ backyardSuppliesEmpty?: boolean;
251
+ backyardPuffleCount?: number;
252
+ };
253
+ /** Furniture placement sent by CPJourney's igloo editor. */
254
+ type IglooFurniturePlacement = {
255
+ furnitureId: number;
256
+ x: number;
257
+ y: number;
258
+ rotation: number;
259
+ frame: number;
260
+ depth: number;
261
+ /** Present in join_igloo snapshots but omitted by editor updates. */
262
+ slot?: number;
263
+ };
264
+ /** Common CPJourney igloo/music store item fields. */
265
+ type IglooStoreItem = {
266
+ id: string;
267
+ name: string;
268
+ cost: number;
269
+ store: number;
270
+ seasonal: number;
271
+ new: number;
272
+ active?: number;
273
+ patched?: number;
274
+ timeAdded?: number;
275
+ };
276
+ /** CPJourney furniture catalog item fields. */
277
+ type FurnitureStoreItem = IglooStoreItem & {
278
+ type: number;
279
+ sort: number;
280
+ member: number;
281
+ bait: number;
282
+ max: number;
283
+ fps?: number;
148
284
  };
149
285
  type NinjaCard = {
150
286
  id: number;
@@ -204,8 +340,19 @@ type SocketIoConnectionOptions = Partial<ManagerOptions & SocketOptions> & {
204
340
  extraHeaders?: Record<string, string>;
205
341
  origin?: string;
206
342
  };
343
+ type AdapterMessage = {
344
+ action: string;
345
+ args: Record<string, unknown>;
346
+ };
207
347
  type ConnectOptions = {
348
+ signal?: AbortSignal;
349
+ timeouts?: Partial<ClientConnectionTimeouts>;
208
350
  onQueueUpdate?: (update: QueueUpdate) => void;
351
+ onLifecycleUpdate?: (update: ClientLifecycleUpdate) => void;
352
+ /** @internal Normalized message delivery installed before session join. */
353
+ onMessage?: (message: AdapterMessage) => void;
354
+ /** @internal Transport disconnect delivery installed before session join. */
355
+ onDisconnect?: (reason: string | null) => void;
209
356
  };
210
357
  declare abstract class BaseAdapter {
211
358
  protected readonly connectionProfile: NormalizedConnectionProfile;
@@ -214,10 +361,14 @@ declare abstract class BaseAdapter {
214
361
  loginMessage: string | null;
215
362
  loginStatus: "active" | "banned";
216
363
  constructor(connectionProfile?: NormalizedConnectionProfile);
217
- abstract login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
364
+ abstract login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
218
365
  abstract connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
219
366
  abstract disconnect(): void;
220
367
  abstract send(action: string, args: Record<string, unknown>): void;
368
+ protected connectionTimeouts(options?: ConnectOptions): ClientConnectionTimeouts;
369
+ protected reportLifecycle(options: ConnectOptions | undefined, phase: ClientLifecyclePhase, queue?: QueueUpdate): void;
370
+ protected resetLoginState(): void;
371
+ protected unsupportedOperation(operation: string): ClientOperationError;
221
372
  protected socketIoOptions(defaultUrlOrOrigin: string): SocketIoConnectionOptions;
222
373
  protected webSocketOptions(defaultUrlOrOrigin: string): {
223
374
  headers?: Record<string, string>;
@@ -250,6 +401,7 @@ declare abstract class BaseAdapter {
250
401
  buddyReject(_id: number): void;
251
402
  buddyRequestSeen(_id: number): void;
252
403
  getBuddy(_id: number, _type: "buddies" | "buddyRequests"): void;
404
+ findBuddy(_id: number): void;
253
405
  removeBuddy(_id: number): void;
254
406
  addIgnore(_id: number): void;
255
407
  removeIgnore(_id: number): void;
@@ -261,11 +413,48 @@ declare abstract class BaseAdapter {
261
413
  getPostcards(): void;
262
414
  getIglooOpen(_igloo: number): void;
263
415
  getIgloos(): void;
264
- getPuffles(_userId: number): void;
416
+ getPuffles(_userId: number, _isBackyard?: boolean): void;
417
+ getAllPuffles(): void;
418
+ getPuffleWellbeing(_puffle: number): void;
419
+ playPuffle(_puffle: number): void;
420
+ restPuffle(_puffle: number): void;
421
+ buyPuffleItem(_puffleId: number, _item: number): void;
422
+ walkPuffle(_puffle: number): void;
423
+ initializePuffleTower(): void;
424
+ getBackyardSupplies(): void;
265
425
  adoptPuffle(_type: number, _name: string): void;
266
426
  getIglooLikes(): void;
267
427
  checkPuffleSprite(_puffleSprite: boolean): void;
268
428
  joinIgloo(_igloo: number, _x?: number, _y?: number): void;
429
+ getStoreMusic(): void;
430
+ buyMusic(_music: string): void;
431
+ getIglooStoreItems(): void;
432
+ buyFurniture(_furniture: string, _amount: number): void;
433
+ updateIglooMusic(_music: string): void;
434
+ updateIglooFurniture(_furniture: Array<{
435
+ furnitureId: number;
436
+ x: number;
437
+ y: number;
438
+ rotation: number;
439
+ frame: number;
440
+ depth: number;
441
+ slot?: number;
442
+ }>): void;
443
+ autoUpdateIglooFurniture(_furniture: Array<{
444
+ furnitureId: number;
445
+ x: number;
446
+ y: number;
447
+ rotation: number;
448
+ frame: number;
449
+ depth: number;
450
+ slot?: number;
451
+ }>): void;
452
+ updateIglooType(_type: number): void;
453
+ openIgloo(): void;
454
+ closeIglooBounds(): void;
455
+ likeIgloo(): void;
456
+ openIglooEditor(): void;
457
+ closeIglooEditor(): void;
269
458
  gameOver(_coins: number): void;
270
459
  collectStamp(_stamp: number): void;
271
460
  /** Fetch ninja rank, progress, and card deck. Listen for `get_ninja` event. */
@@ -288,7 +477,8 @@ declare abstract class BaseAdapter {
288
477
 
289
478
  declare class CpjourneyAdapter extends BaseAdapter {
290
479
  readonly id = "CPJourney";
291
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
480
+ private gameToken;
481
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
292
482
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
293
483
  private queueForServer;
294
484
  send(action: string, args: Record<string, unknown>): void;
@@ -317,6 +507,7 @@ declare class CpjourneyAdapter extends BaseAdapter {
317
507
  buddyReject(id: number): void;
318
508
  buddyRequestSeen(id: number): void;
319
509
  getBuddy(id: number, type: "buddies" | "buddyRequests"): void;
510
+ findBuddy(id: number): void;
320
511
  removeBuddy(id: number): void;
321
512
  addIgnore(id: number): void;
322
513
  removeIgnore(id: number): void;
@@ -328,11 +519,48 @@ declare class CpjourneyAdapter extends BaseAdapter {
328
519
  getPostcards(): void;
329
520
  getIglooOpen(igloo: number): void;
330
521
  getIgloos(): void;
331
- getPuffles(userId: number): void;
522
+ getPuffles(userId: number, isBackyard?: boolean): void;
523
+ getAllPuffles(): void;
524
+ getPuffleWellbeing(puffle: number): void;
525
+ playPuffle(puffle: number): void;
526
+ restPuffle(puffle: number): void;
527
+ buyPuffleItem(puffleId: number, item: number): void;
528
+ walkPuffle(puffle: number): void;
529
+ initializePuffleTower(): void;
530
+ getBackyardSupplies(): void;
332
531
  adoptPuffle(type: number, name: string): void;
333
532
  getIglooLikes(): void;
334
533
  checkPuffleSprite(puffleSprite: boolean): void;
335
534
  joinIgloo(igloo: number, x?: number, y?: number): void;
535
+ getStoreMusic(): void;
536
+ buyMusic(music: string): void;
537
+ getIglooStoreItems(): void;
538
+ buyFurniture(furniture: string, amount: number): void;
539
+ updateIglooMusic(music: string): void;
540
+ updateIglooFurniture(furniture: Array<{
541
+ furnitureId: number;
542
+ x: number;
543
+ y: number;
544
+ rotation: number;
545
+ frame: number;
546
+ depth: number;
547
+ slot?: number;
548
+ }>): void;
549
+ autoUpdateIglooFurniture(furniture: Array<{
550
+ furnitureId: number;
551
+ x: number;
552
+ y: number;
553
+ rotation: number;
554
+ frame: number;
555
+ depth: number;
556
+ slot?: number;
557
+ }>): void;
558
+ updateIglooType(type: number): void;
559
+ openIgloo(): void;
560
+ closeIglooBounds(): void;
561
+ likeIgloo(): void;
562
+ openIglooEditor(): void;
563
+ closeIglooEditor(): void;
336
564
  gameOver(coins: number): void;
337
565
  collectStamp(stamp: number): void;
338
566
  getNinja(): void;
@@ -343,13 +571,13 @@ declare class CpjourneyAdapter extends BaseAdapter {
343
571
  selectCard(slot: number): void;
344
572
  loadAnimation(animation: string): void;
345
573
  joinMat(waddle: number): void;
346
- private createSocket;
574
+ protected createSocket(path: string): Socket;
347
575
  }
348
576
 
349
577
  declare class CplegacyAdapter extends BaseAdapter {
350
578
  readonly id = "CPLegacy";
351
579
  private version;
352
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
580
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
353
581
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
354
582
  send(action: string, args: Record<string, unknown>): void;
355
583
  disconnect(): void;
@@ -385,48 +613,14 @@ declare class CplegacyAdapter extends BaseAdapter {
385
613
  gameOver(coins: number): void;
386
614
  collectStamp(stamp: number): void;
387
615
  private postLogin;
388
- }
389
-
390
- declare class CpzeroAdapter extends BaseAdapter {
391
- readonly id = "CPZero";
392
- private sfs;
393
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
394
- connect(_serverName: string, loginResult: LoginResult, _options?: ConnectOptions): Promise<socket_io_client.Socket>;
395
- send(action: string, args: Record<string, unknown>): void;
396
- disconnect(): void;
397
- normalizeUser(raw: Record<string, unknown>): RoomUser;
398
- normalizePlayer(raw: Record<string, unknown>): PlayerData;
399
- sendMessage(message: string): void;
400
- sendEmote(emote: number): void;
401
- sendSafe(safe: number): void;
402
- walk(x: number, y: number): void;
403
- sendFrame(frame: number): void;
404
- snowball(x: number, y: number): void;
405
- joinRoom(room: number, x?: number, y?: number): void;
406
- addItem(item: number): void;
407
- equipColor(item: number): void;
408
- equipHead(item: number): void;
409
- equipFace(item: number): void;
410
- equipNeck(item: number): void;
411
- equipBody(item: number): void;
412
- equipHand(item: number): void;
413
- equipFeet(item: number): void;
414
- equipFlag(item: number): void;
415
- equipPhoto(item: number): void;
416
- getPlayer(id: number): void;
417
- joinIgloo(igloo: number, _x?: number, _y?: number): void;
418
- /**
419
- * Process a batch of `%xt%` messages that may be concatenated in a single
420
- * WebSocket frame (separated by \0 already split, but multiple %xt% in one string).
421
- */
422
- private processXtBatch;
616
+ protected createSocket(serverName: string): Socket;
423
617
  }
424
618
 
425
619
  declare class NewcpAdapter extends BaseAdapter {
426
620
  readonly id = "NewCP";
427
621
  private encryptor;
428
622
  private worlds;
429
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
623
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
430
624
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
431
625
  send(action: string, args: Record<string, unknown>): void;
432
626
  disconnect(): void;
@@ -457,13 +651,13 @@ declare class NewcpAdapter extends BaseAdapter {
457
651
  removeIgnore(id: number): void;
458
652
  getPlayer(id: number): void;
459
653
  joinIgloo(igloo: number, x?: number, y?: number): void;
460
- private createSocket;
654
+ protected createSocket(host: string, path: string): Socket;
461
655
  private loadWorlds;
462
656
  }
463
657
 
464
658
  declare class PenguinoriginsAdapter extends BaseAdapter {
465
659
  readonly id = "PenguinOrigins";
466
- login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult>;
660
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<LoginResult>;
467
661
  connect(serverName: string, loginResult: LoginResult, options?: ConnectOptions): Promise<Socket>;
468
662
  send(action: string, args: Record<string, unknown>): void;
469
663
  disconnect(): void;
@@ -493,13 +687,12 @@ declare class PenguinoriginsAdapter extends BaseAdapter {
493
687
  getIglooOpen(igloo: number): void;
494
688
  joinIgloo(igloo: number, x?: number, y?: number): void;
495
689
  gameOver(coins: number): void;
496
- private createSocket;
690
+ protected createSocket(path: string): Socket;
497
691
  }
498
692
 
499
693
  declare const ADAPTERS: {
500
694
  readonly CPJourney: typeof CpjourneyAdapter;
501
695
  readonly CPLegacy: typeof CplegacyAdapter;
502
- readonly CPZero: typeof CpzeroAdapter;
503
696
  readonly NewCP: typeof NewcpAdapter;
504
697
  readonly PenguinOrigins: typeof PenguinoriginsAdapter;
505
698
  };
@@ -577,6 +770,7 @@ type ClientMessages = {
577
770
  get_igloos: Record<string, never>;
578
771
  get_puffles: {
579
772
  userId: number;
773
+ isBackyard?: boolean;
580
774
  };
581
775
  get_igloo_likes: Record<string, never>;
582
776
  join_igloo: {
@@ -628,6 +822,54 @@ type ClientMessages = {
628
822
  check_puffle_sprite: {
629
823
  puffleSprite: unknown;
630
824
  };
825
+ get_all_puffles: Record<string, never>;
826
+ get_wellbeing: {
827
+ puffle: number;
828
+ };
829
+ puffle_play: {
830
+ puffle: number;
831
+ };
832
+ update_puffle_rest: {
833
+ puffle: number;
834
+ };
835
+ puffle_buy_item: {
836
+ puffleId: number;
837
+ item: number;
838
+ };
839
+ walk_puffle: {
840
+ puffle: number;
841
+ };
842
+ backyard_supplies: Record<string, never>;
843
+ buddy_find: {
844
+ id: number;
845
+ };
846
+ get_store_music: Record<string, never>;
847
+ add_music: {
848
+ music: string;
849
+ };
850
+ get_igloostore_items: Record<string, never>;
851
+ add_furniture: {
852
+ furniture: string;
853
+ amount: number;
854
+ };
855
+ update_music: {
856
+ music: string;
857
+ };
858
+ update_furniture: {
859
+ furniture: IglooFurniturePlacement[];
860
+ };
861
+ update_furniture_auto: {
862
+ furniture: IglooFurniturePlacement[];
863
+ };
864
+ update_igloo: {
865
+ type: number;
866
+ };
867
+ open_igloo: Record<string, never>;
868
+ close_igloo_bounds: Record<string, never>;
869
+ like_igloo: Record<string, never>;
870
+ igloo_editor_open: Record<string, never>;
871
+ igloo_editor_closed: Record<string, never>;
872
+ tower_init: Record<string, never>;
631
873
  queue_server_join: {
632
874
  server: string;
633
875
  };
@@ -827,11 +1069,74 @@ type ServerMessages = {
827
1069
  };
828
1070
  get_puffles: {
829
1071
  userId: number;
830
- puffles: {
831
- id: number;
832
- type: number;
833
- }[];
1072
+ puffles: Puffle[];
1073
+ };
1074
+ get_all_puffles: {
1075
+ puffles: Puffle[];
1076
+ };
1077
+ get_wellbeing: PuffleWellbeing;
1078
+ get_walking_puffle: {
1079
+ puffle: Puffle;
1080
+ };
1081
+ update_wellbeing: PuffleWellbeing;
1082
+ puffle_levelup: {
1083
+ puffleId: number;
1084
+ level: number;
1085
+ };
1086
+ puffle_popup: {
1087
+ puffleId: number;
1088
+ popupId: number;
1089
+ };
1090
+ buy_puffle_item: {
1091
+ puffleId: number;
1092
+ item: number;
1093
+ coins: number;
1094
+ puffleInventory: Record<string, unknown>;
1095
+ };
1096
+ walk_puffle: {
1097
+ user: number;
1098
+ puffle: number;
1099
+ type: number;
1100
+ };
1101
+ backyard_supplies: {
1102
+ supplyCost: number;
1103
+ puffleCount: number;
1104
+ supplyState: number;
1105
+ };
1106
+ buddy_find: {
1107
+ find: number;
1108
+ username: string;
1109
+ game: boolean;
1110
+ };
1111
+ receive_postcard: Postcard;
1112
+ get_store_music: {
1113
+ music: IglooStoreItem[];
1114
+ };
1115
+ add_music: {
1116
+ music: string;
1117
+ coins: number;
1118
+ };
1119
+ get_igloostore_items: {
1120
+ furniture: FurnitureStoreItem[];
1121
+ flooring: IglooStoreItem[];
1122
+ igloo: IglooStoreItem[];
1123
+ location: IglooStoreItem[];
1124
+ };
1125
+ add_furniture: {
1126
+ furniture: string;
1127
+ coins: number;
1128
+ amount: number;
1129
+ };
1130
+ update_music: {
1131
+ music: string;
1132
+ };
1133
+ igloo_open_status: {
1134
+ status: number;
1135
+ };
1136
+ igloo_bounds_status: {
1137
+ status: number;
834
1138
  };
1139
+ igloo_liked: Record<string, never>;
835
1140
  update_player: {
836
1141
  id: number;
837
1142
  item: number;
@@ -878,7 +1183,7 @@ type ServerMessages = {
878
1183
  transform: number;
879
1184
  };
880
1185
  adopt_puffle: {
881
- puffle: unknown;
1186
+ puffle?: unknown;
882
1187
  coins: number;
883
1188
  };
884
1189
  /** Generic server info/notification message */
@@ -889,7 +1194,7 @@ type ServerMessages = {
889
1194
  action: string;
890
1195
  args: Record<string, unknown>;
891
1196
  };
892
- disconnect: undefined;
1197
+ disconnect: ClientDisconnectInfo;
893
1198
  /** Ninja rank, progress, and full card deck */
894
1199
  get_ninja: NinjaData;
895
1200
  /** State of all Dojo mats — keys are mat IDs, values are seat arrays */
@@ -954,26 +1259,30 @@ type ServerMessages = {
954
1259
  message: string;
955
1260
  };
956
1261
  };
1262
+ /** CPJourney-only commands captured from its Socket.IO protocol. */
1263
+ type CpjourneyClientMessages = Pick<ClientMessages, "get_puffles" | "adopt_puffle" | "check_puffle_sprite" | "get_all_puffles" | "get_wellbeing" | "puffle_play" | "update_puffle_rest" | "puffle_buy_item" | "walk_puffle" | "backyard_supplies" | "buddy_find" | "get_store_music" | "add_music" | "get_igloostore_items" | "add_furniture" | "update_music" | "update_furniture" | "update_furniture_auto" | "update_igloo" | "open_igloo" | "close_igloo_bounds" | "like_igloo" | "igloo_editor_open" | "igloo_editor_closed" | "tower_init">;
1264
+ /** CPJourney-only events captured from its Socket.IO protocol. */
1265
+ type CpjourneyServerMessages = Pick<ServerMessages, "game_over" | "get_postcards" | "join_igloo" | "get_puffles" | "adopt_puffle" | "get_all_puffles" | "get_wellbeing" | "get_walking_puffle" | "update_wellbeing" | "puffle_levelup" | "puffle_popup" | "buy_puffle_item" | "walk_puffle" | "backyard_supplies" | "buddy_find" | "receive_postcard" | "get_store_music" | "add_music" | "get_igloostore_items" | "add_furniture" | "update_music" | "igloo_open_status" | "igloo_bounds_status" | "igloo_liked">;
957
1266
 
958
- type WaitForFn = <K extends keyof ServerMessages>(event: K, timeout?: number) => Promise<ServerMessages[K]>;
1267
+ type RequestFn = <K extends keyof ServerMessages>(event: K, send: () => void, options?: ClientOperationOptions, matches?: (args: ServerMessages[K]) => boolean) => Promise<ServerMessages[K]>;
959
1268
  declare class CardJitsu {
960
1269
  private adapter;
961
- private waitFor;
962
- constructor(adapter: BaseAdapter, waitFor: WaitForFn);
1270
+ private request;
1271
+ constructor(adapter: BaseAdapter, request: RequestFn);
963
1272
  /** Fetch ninja rank, progress, and card deck. Resolves with ninja data. */
964
- getNinja(): Promise<ServerMessages["get_ninja"]>;
1273
+ getNinja(options?: ClientOperationOptions): Promise<ServerMessages["get_ninja"]>;
965
1274
  /** Fetch state of all Dojo mats. Resolves with mat state. */
966
- getMats(): Promise<ServerMessages["get_waddles"]>;
1275
+ getMats(options?: ClientOperationOptions): Promise<ServerMessages["get_waddles"]>;
967
1276
  /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */
968
1277
  joinMat(waddle: number): void;
969
1278
  /** Join Sensei matchmaking queue. Resolves when server acknowledges. */
970
- joinMatchmaking(): Promise<ServerMessages["join_matchmaking"]>;
1279
+ joinMatchmaking(options?: ClientOperationOptions): Promise<ServerMessages["join_matchmaking"]>;
971
1280
  /** Leave Sensei matchmaking queue. */
972
1281
  leaveMatchmaking(): void;
973
1282
  /** Start a Card-Jitsu match after entering a game room. Resolves with player info. */
974
- startGame(): Promise<ServerMessages["start_game"]>;
1283
+ startGame(options?: ClientOperationOptions): Promise<ServerMessages["start_game"]>;
975
1284
  /** Play a card from your hand by slot index. Resolves when server acknowledges. */
976
- selectCard(slot: number): Promise<ServerMessages["move_my_card"]>;
1285
+ selectCard(slot: number, options?: ClientOperationOptions): Promise<ServerMessages["move_my_card"]>;
977
1286
  /** Preload a power card animation asset. */
978
1287
  loadAnimation(animation: string): void;
979
1288
  }
@@ -993,12 +1302,20 @@ declare class Client extends EventEmitter {
993
1302
  private loginResult;
994
1303
  private log;
995
1304
  private _cardJitsu;
1305
+ private intentionalDisconnect;
1306
+ private disconnectNotified;
1307
+ private connectionFailure;
1308
+ private lifecycleReporter;
1309
+ private requestTails;
1310
+ private disconnectEpoch;
1311
+ private lastDisconnectInfo;
996
1312
  get loginMessage(): string | null;
997
1313
  get loginStatus(): "active" | "banned";
998
1314
  get cardJitsu(): CardJitsu;
999
1315
  constructor(server: AdapterName, options?: ClientOptions);
1000
- login(options: LoginOptions | TokenLoginOptions): Promise<ServerInfo[]>;
1316
+ login(options: LoginOptions | TokenLoginOptions, operationOptions?: ClientOperationOptions): Promise<ServerInfo[]>;
1001
1317
  connect(serverName: string, options?: ConnectOptions): Promise<void>;
1318
+ private waitForInitialState;
1002
1319
  on<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this;
1003
1320
  on(event: string, listener: (...args: unknown[]) => void): this;
1004
1321
  off<K extends keyof ServerMessages>(event: K, listener: ServerMessageHandler<K>): this;
@@ -1007,16 +1324,20 @@ declare class Client extends EventEmitter {
1007
1324
  once(event: string, listener: (...args: unknown[]) => void): this;
1008
1325
  emit<K extends keyof ServerMessages>(event: K, args: ServerMessages[K]): boolean;
1009
1326
  emit(event: string, ...args: unknown[]): boolean;
1010
- /** Wait for a server event. Resolves with the event payload. Optional timeout in ms. Rejects on disconnect. */
1327
+ /** Wait for a server event. Resolves with the event payload and rejects on timeout, abort, or disconnect. */
1011
1328
  waitFor<K extends keyof ServerMessages>(event: K, timeout?: number): Promise<ServerMessages[K]>;
1329
+ waitFor<K extends keyof ServerMessages>(event: K, options?: ClientOperationOptions): Promise<ServerMessages[K]>;
1330
+ private waitForEvent;
1331
+ private request;
1332
+ private waitForRequestTurn;
1012
1333
  sendMessage(message: string): void;
1013
1334
  sendEmote(emote: number): void;
1014
1335
  sendSafe(safe: number): void;
1015
1336
  walk(x: number, y: number): void;
1016
1337
  sendFrame(frame: number, set?: boolean): void;
1017
1338
  snowball(x: number, y: number): void;
1018
- joinRoom(room: number, x?: number, y?: number): Promise<ServerMessages["join_room"]>;
1019
- addItem(item: number): Promise<ServerMessages["add_item"]>;
1339
+ joinRoom(room: number, x?: number, y?: number, options?: ClientOperationOptions): Promise<ServerMessages["join_room"]>;
1340
+ addItem(item: number, options?: ClientOperationOptions): Promise<ServerMessages["add_item"]>;
1020
1341
  equipColor(item: number): void;
1021
1342
  equipHead(item: number): void;
1022
1343
  equipFace(item: number): void;
@@ -1027,32 +1348,59 @@ declare class Client extends EventEmitter {
1027
1348
  equipFlag(item: number): void;
1028
1349
  equipPhoto(item: number): void;
1029
1350
  buddyRequest(id: number): void;
1030
- buddyAccept(id: number): Promise<ServerMessages["buddy_accept"]>;
1031
- buddyReject(id: number): Promise<ServerMessages["buddy_reject"]>;
1032
- buddyRequestSeen(id: number): Promise<ServerMessages["buddy_request_seen"]>;
1033
- getBuddy(id: number, type: "buddies" | "buddyRequests"): Promise<ServerMessages["get_buddy"]>;
1351
+ buddyAccept(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_accept"]>;
1352
+ buddyReject(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_reject"]>;
1353
+ buddyRequestSeen(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_request_seen"]>;
1354
+ getBuddy(id: number, type: "buddies" | "buddyRequests", options?: ClientOperationOptions): Promise<ServerMessages["get_buddy"]>;
1355
+ findBuddy(id: number, options?: ClientOperationOptions): Promise<ServerMessages["buddy_find"]>;
1034
1356
  removeBuddy(id: number): void;
1035
- addIgnore(id: number): Promise<ServerMessages["ignore_add"]>;
1036
- removeIgnore(id: number): Promise<ServerMessages["ignore_remove"]>;
1037
- getPlayer(id: number): Promise<ServerMessages["get_player"]>;
1038
- getAllSlots(): Promise<ServerMessages["slot"]>;
1039
- getMascots(): Promise<ServerMessages["get_mascots"]>;
1040
- sendPostcard(userId: number, cardId: string): Promise<ServerMessages["send_postcard"]>;
1041
- getStamps(userId: number): Promise<ServerMessages["stamps_result"]>;
1042
- getPostcards(): Promise<ServerMessages["get_postcards"]>;
1043
- getIglooOpen(igloo: number): Promise<ServerMessages["get_igloo_open"]>;
1044
- getIgloos(): Promise<ServerMessages["get_igloos"]>;
1045
- getPuffles(userId: number): Promise<ServerMessages["get_puffles"]>;
1046
- adoptPuffle(type: number, name: string): Promise<ServerMessages["adopt_puffle"]>;
1047
- getIglooLikes(): Promise<ServerMessages["get_igloo_likes"]>;
1357
+ addIgnore(id: number, options?: ClientOperationOptions): Promise<ServerMessages["ignore_add"]>;
1358
+ removeIgnore(id: number, options?: ClientOperationOptions): Promise<ServerMessages["ignore_remove"]>;
1359
+ getPlayer(id: number, options?: ClientOperationOptions): Promise<ServerMessages["get_player"]>;
1360
+ getAllSlots(options?: ClientOperationOptions): Promise<ServerMessages["slot"]>;
1361
+ getMascots(options?: ClientOperationOptions): Promise<ServerMessages["get_mascots"]>;
1362
+ sendPostcard(userId: number, cardId: string, options?: ClientOperationOptions): Promise<ServerMessages["send_postcard"]>;
1363
+ getStamps(userId: number, options?: ClientOperationOptions): Promise<ServerMessages["stamps_result"]>;
1364
+ getPostcards(options?: ClientOperationOptions): Promise<ServerMessages["get_postcards"]>;
1365
+ getIglooOpen(igloo: number, options?: ClientOperationOptions): Promise<ServerMessages["get_igloo_open"]>;
1366
+ getIgloos(options?: ClientOperationOptions): Promise<ServerMessages["get_igloos"]>;
1367
+ getPuffles(userId: number, options?: ClientOperationOptions & {
1368
+ isBackyard?: boolean;
1369
+ }): Promise<ServerMessages["get_puffles"]>;
1370
+ getAllPuffles(options?: ClientOperationOptions): Promise<ServerMessages["get_all_puffles"]>;
1371
+ getPuffleWellbeing(puffle: number, options?: ClientOperationOptions): Promise<ServerMessages["get_wellbeing"]>;
1372
+ playPuffle(puffle: number): void;
1373
+ restPuffle(puffle: number): void;
1374
+ buyPuffleItem(puffleId: number, item: number, options?: ClientOperationOptions): Promise<ServerMessages["buy_puffle_item"]>;
1375
+ walkPuffle(puffle: number, options?: ClientOperationOptions): Promise<ServerMessages["get_walking_puffle"]>;
1376
+ /** CPJourney sends tower_init after its walking-puffle acknowledgement. */
1377
+ initializePuffleTower(): void;
1378
+ getBackyardSupplies(options?: ClientOperationOptions): Promise<ServerMessages["backyard_supplies"]>;
1379
+ adoptPuffle(type: number, name: string, options?: ClientOperationOptions): Promise<ServerMessages["adopt_puffle"]>;
1380
+ getIglooLikes(options?: ClientOperationOptions): Promise<ServerMessages["get_igloo_likes"]>;
1048
1381
  checkPuffleSprite(puffleSprite: boolean): void;
1049
- joinIgloo(igloo: number, x?: number, y?: number): Promise<ServerMessages["join_igloo"]>;
1050
- gameOver(coins: number): Promise<ServerMessages["game_over"]>;
1051
- collectStamp(stamp: number): Promise<ServerMessages["stamp_earned"]>;
1382
+ joinIgloo(igloo: number, x?: number, y?: number, options?: ClientOperationOptions): Promise<ServerMessages["join_igloo"]>;
1383
+ getStoreMusic(options?: ClientOperationOptions): Promise<ServerMessages["get_store_music"]>;
1384
+ buyMusic(music: string, options?: ClientOperationOptions): Promise<ServerMessages["add_music"]>;
1385
+ getIglooStoreItems(options?: ClientOperationOptions): Promise<ServerMessages["get_igloostore_items"]>;
1386
+ buyFurniture(furniture: string, amount?: number, options?: ClientOperationOptions): Promise<ServerMessages["add_furniture"]>;
1387
+ updateIglooMusic(music: string, options?: ClientOperationOptions): Promise<ServerMessages["update_music"]>;
1388
+ updateIglooFurniture(furniture: ClientMessages["update_furniture"]["furniture"]): void;
1389
+ autoUpdateIglooFurniture(furniture: ClientMessages["update_furniture_auto"]["furniture"]): void;
1390
+ updateIglooType(type: number): void;
1391
+ openIgloo(options?: ClientOperationOptions): Promise<ServerMessages["igloo_open_status"]>;
1392
+ closeIglooBounds(options?: ClientOperationOptions): Promise<ServerMessages["igloo_bounds_status"]>;
1393
+ likeIgloo(options?: ClientOperationOptions): Promise<ServerMessages["igloo_liked"]>;
1394
+ openIglooEditor(): void;
1395
+ closeIglooEditor(): void;
1396
+ gameOver(coins: number, options?: ClientOperationOptions): Promise<ServerMessages["game_over"]>;
1397
+ collectStamp(stamp: number, options?: ClientOperationOptions): Promise<ServerMessages["stamp_earned"]>;
1052
1398
  sleep(ms: number): Promise<void>;
1053
1399
  disconnect(): void;
1400
+ private reportLifecycle;
1401
+ private handleAdapterDisconnect;
1054
1402
  private cleanup;
1055
1403
  private handleMessage;
1056
1404
  }
1057
1405
 
1058
- export { type AdapterName, BaseAdapter, type Buddy, CardJitsu, Client, type ClientMessages, type ClientOptions, type ConnectOptions, type ConnectionProfile, type ConnectionProfileInput, type ConnectionProfilePreset, type GameCard, type GamePlayer, type LogFn, type LoginOptions, type LoginResult, type Mascot, type MatState, type NinjaCard, type NinjaData, type NinjaProgress, type PlayerAppearance, type PlayerData, type PlayerSettings, type Postcard, type QueueUpdate, type RevealedCard, type RoomUser, type RoundResult, type ServerInfo, type ServerMessages, type TokenLoginOptions };
1406
+ export { type AdapterName, BaseAdapter, type Buddy, CardJitsu, Client, type ClientConnectionTimeouts, type ClientDisconnectInfo, type ClientLifecyclePhase, type ClientLifecycleUpdate, type ClientMessages, ClientOperationError, type ClientOperationErrorCategory, type ClientOperationErrorOptions, type ClientOperationOptions, type ClientOptions, type ConnectOptions, type ConnectionProfile, type ConnectionProfileInput, type ConnectionProfilePreset, type CpjourneyClientMessages, type CpjourneyServerMessages, DEFAULT_CLIENT_CONNECTION_TIMEOUTS, type FurnitureStoreItem, type GameCard, type GamePlayer, type IglooFurniturePlacement, type IglooStoreItem, type LogFn, type LoginOptions, type LoginResult, type Mascot, type MatState, type NinjaCard, type NinjaData, type NinjaProgress, type PlayerAppearance, type PlayerData, type PlayerSettings, type Postcard, type Puffle, type PuffleWellbeing, type QueueUpdate, type RevealedCard, type RoomUser, type RoundResult, type ServerInfo, type ServerMessages, type TokenLoginOptions, sanitizeClientErrorMessage };