@lokiplay/sdk 0.1.1 → 0.2.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/README.md CHANGED
@@ -4,7 +4,7 @@ JavaScript client SDK for authenticating players, joining Loki multiplayer
4
4
  rooms, sending actions and events, and subscribing to server messages.
5
5
 
6
6
  ```sh
7
- npm install @lokiplay/sdk
7
+ npm install @lokiplay/sdk@0.2.0
8
8
  ```
9
9
 
10
10
  Use `FirstPartyTransport` for production. It defaults to
@@ -19,5 +19,38 @@ game manifest allowlist.
19
19
 
20
20
  `LokiClient` supports rooms, invite resolution, matchmaking, actions, events,
21
21
  host state, snapshots, presence, chat, private scores, token refresh, reconnect,
22
- and host-migration messages. Host authority is suitable for casual/unranked
23
- games, not ranked anti-cheat.
22
+ and host-migration messages. Loki creates every room and issues the shareable
23
+ invite code. Call `createRoom()` and `joinRoom({ inviteCode })` and do not invent
24
+ room keys.
25
+
26
+ Prefer `createSynchronizedRoom()` for shared state. Supply opaque state, opaque
27
+ actions, and a reducer. Loki sequences actions, commits only from the current
28
+ authority, tracks `stateVersion`, deduplicates action IDs, restores snapshots,
29
+ and exposes membership and connection status. Low-level `sendAction()` and
30
+ `sendHostState()` remain available. Host authority is suitable for casual
31
+ unranked sessions, not ranked integrity.
32
+
33
+ Generic integration steps:
34
+
35
+ 1. Install the exact published SDK version for this release.
36
+ 2. Define this project's state and action schemas.
37
+ 3. Define a synchronous, deterministic, JSON-compatible reducer.
38
+ 4. Create or join with `create()` or `join({ inviteCode })`.
39
+ 5. Subscribe to snapshots for state, members, authority, and connection.
40
+ 6. Dispatch actions and wait for authoritative confirmation.
41
+ 7. Render connection and `lastError` from the snapshot.
42
+ 8. Handle rejected actions without inventing a parallel protocol.
43
+ 9. Build and deploy from this project's own repository.
44
+
45
+ Reducers must return quickly. Loki clones reducer inputs and catches thrown
46
+ errors, but a synchronous infinite loop cannot be interrupted without changing
47
+ the reducer API. Do not perform I/O or rendering inside `reduce`. Reducers must
48
+ be synchronous, deterministic, and JSON-compatible. Only the current host runs
49
+ `reduce`; members wait for an authoritative `state` acknowledgement keyed by
50
+ `(senderId, actionId)`.
51
+
52
+ `create()`, `join({ inviteCode })`, `dispatch(action)`, `leave()`, and
53
+ `reconnect()` are the shared synchronized-room API. A failed `leave()` retains
54
+ the room identity in `leave_failed` and blocks a new join until `leave()`
55
+ succeeds or `close()` abandons the handle. 0.2.0 clients fail fast when a
56
+ snapshot does not advertise `capabilities.synchronized_rooms`.
package/dist/index.d.ts CHANGED
@@ -1,33 +1,41 @@
1
1
  import { type ClientEnvelope, type ServerEnvelope } from "@lokiplay/protocol";
2
+ import { SynchronizedRoom, type ConnectionEvent, type SynchronizedRoomOptions } from "./synchronized-room.js";
3
+ export { SYNCHRONIZED_ROOM_ACTION_TTL_MS, SYNCHRONIZED_ROOM_COMMIT_TIMEOUT_MS, SYNCHRONIZED_ROOM_MAX_MESSAGE_BYTES, SYNCHRONIZED_ROOM_MAX_PENDING, SYNCHRONIZED_ROOM_MAX_RECENT_ACTIONS, SYNCHRONIZED_ROOM_MAX_REDUCER_MS, SynchronizedRoom, SynchronizedRoomError, } from "./synchronized-room.js";
4
+ export type { ActionContext, CommittedTransition, ConnectionEvent, ConnectionState, RoomMember, Schema, SynchronizedRoomOutcome, SynchronizedRoomSnapshot, } from "./synchronized-room.js";
2
5
  export declare const LOKI_API_ORIGIN = "https://api.lokiplay.cc";
6
+ export type JoinedRoom = {
7
+ roomId: string;
8
+ inviteCode: string;
9
+ snapshot: ServerEnvelope;
10
+ };
11
+ export declare function lokiErrorFromUnknown(error: unknown): Promise<Error>;
3
12
  export interface LokiTransport {
4
13
  authenticate(token: string): Promise<{
5
14
  playerId: string;
6
15
  }>;
16
+ createRoom(input: {
17
+ projectId: string;
18
+ }): Promise<JoinedRoom>;
7
19
  joinRoom(input: {
8
20
  projectId: string;
9
- roomKey: string;
10
- }): Promise<{
11
- roomId: string;
12
- snapshot: ServerEnvelope;
13
- }>;
21
+ inviteCode: string;
22
+ }): Promise<JoinedRoom>;
14
23
  send(message: ClientEnvelope): Promise<void>;
15
24
  subscribe(listener: (message: unknown) => void): () => void;
16
25
  resolveInvite?(inviteCode: string): Promise<{
17
26
  roomId: string;
27
+ inviteCode: string;
18
28
  }>;
19
29
  matchmake?(input: {
20
30
  minPlayers: number;
21
31
  maxPlayers: number;
22
32
  teamSize?: number;
23
- }): Promise<{
24
- roomId: string;
25
- snapshot: ServerEnvelope;
26
- }>;
33
+ }): Promise<JoinedRoom>;
27
34
  leaveRoom?(roomId: string): Promise<void>;
28
35
  reconnect?(): Promise<void>;
29
36
  refresh?(): Promise<void>;
30
37
  close(): Promise<void>;
38
+ subscribeConnection?(listener: (event: ConnectionEvent) => void): () => void;
31
39
  }
32
40
  export interface LokiClientOptions {
33
41
  projectId: string;
@@ -36,26 +44,44 @@ export interface LokiClientOptions {
36
44
  export declare class LokiClient {
37
45
  #private;
38
46
  constructor(options: LokiClientOptions);
47
+ get playerId(): string | undefined;
48
+ get roomId(): string | undefined;
49
+ get inviteCode(): string;
39
50
  initialize(): void;
51
+ createSynchronizedRoom<State, Action>(options: SynchronizedRoomOptions<State, Action>): SynchronizedRoom<State, Action>;
52
+ onConnection(listener: (event: ConnectionEvent) => void): () => void;
40
53
  authenticate(token: string): Promise<{
41
54
  playerId: string;
42
55
  }>;
43
- joinRoom(roomKey: string): Promise<ServerEnvelope>;
44
- sendAction(payload: unknown): Promise<void>;
56
+ createRoom(): Promise<JoinedRoom>;
57
+ joinRoom(input: {
58
+ inviteCode: string;
59
+ }): Promise<JoinedRoom>;
60
+ sendAction(payload: unknown, options?: {
61
+ actionId?: string;
62
+ }): Promise<void>;
45
63
  sendEvent(payload: unknown, reliable?: boolean): Promise<void>;
46
- sendHostState(expectedVersion: number, state: unknown): Promise<void>;
64
+ sendHostState(expectedVersion: number, state: unknown, options?: {
65
+ actionId?: string;
66
+ expectedStateVersion?: number;
67
+ senderId?: string;
68
+ }): Promise<void>;
69
+ sendActionRejection(actionId: string, outcome: "rejected" | "invalid", message: string, options?: {
70
+ senderId?: string;
71
+ }): Promise<void>;
47
72
  requestSnapshot(): Promise<void>;
48
73
  sendChat(text: string, channel?: "lobby" | "match"): Promise<void>;
49
74
  submitScore(leaderboardId: string, score: number, subscore?: number): Promise<void>;
50
75
  resolveInvite(inviteCode: string): Promise<{
51
76
  roomId: string;
77
+ inviteCode: string;
52
78
  }>;
53
79
  matchmake(input: {
54
80
  minPlayers: number;
55
81
  maxPlayers: number;
56
82
  teamSize?: number;
57
- }): Promise<ServerEnvelope>;
58
- leaveRoom(): Promise<void>;
83
+ }): Promise<JoinedRoom>;
84
+ leaveRoom(roomId?: string): Promise<void>;
59
85
  reconnect(): Promise<void>;
60
86
  refresh(): Promise<void>;
61
87
  onMessage(listener: (message: ServerEnvelope) => void): () => void;
@@ -80,26 +106,25 @@ export declare class FirstPartyTransport implements LokiTransport {
80
106
  authenticate(token: string): Promise<{
81
107
  playerId: string;
82
108
  }>;
109
+ createRoom(_input: {
110
+ projectId: string;
111
+ }): Promise<JoinedRoom>;
83
112
  joinRoom(input: {
84
113
  projectId: string;
85
- roomKey: string;
86
- }): Promise<{
87
- roomId: string;
88
- snapshot: ServerEnvelope;
89
- }>;
114
+ inviteCode: string;
115
+ }): Promise<JoinedRoom>;
90
116
  resolveInvite(inviteCode: string): Promise<{
91
117
  roomId: string;
118
+ inviteCode: string;
92
119
  }>;
93
120
  matchmake(input: {
94
121
  minPlayers: number;
95
122
  maxPlayers: number;
96
123
  teamSize?: number;
97
- }): Promise<{
98
- roomId: string;
99
- snapshot: ServerEnvelope;
100
- }>;
124
+ }): Promise<JoinedRoom>;
101
125
  send(message: ClientEnvelope): Promise<void>;
102
126
  subscribe(listener: (message: unknown) => void): () => void;
127
+ subscribeConnection(listener: (event: ConnectionEvent) => void): () => void;
103
128
  leaveRoom(roomId: string): Promise<void>;
104
129
  refresh(): Promise<void>;
105
130
  reconnect(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}