@remix-gg/sdk 0.7.0 → 0.8.1
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.mts +42 -58
- package/dist/index.d.ts +42 -58
- package/dist/index.js +54 -103
- package/dist/index.min.js +42 -91
- package/dist/index.min.js.map +3 -3
- package/dist/index.mjs +54 -101
- package/package.json +4 -2
- package/dist/index.js.map +0 -10
- package/dist/index.mjs.map +0 -10
package/dist/index.d.mts
CHANGED
|
@@ -42,15 +42,31 @@ type GameInfo = {
|
|
|
42
42
|
id: string;
|
|
43
43
|
gameState: GameState;
|
|
44
44
|
} | null;
|
|
45
|
+
/**
|
|
46
|
+
* Present only when the host has level progression enabled for this session.
|
|
47
|
+
* Games must key level mode off this block's presence, not their own level
|
|
48
|
+
* content — the platform can disable it (e.g. feature gating) at any time.
|
|
49
|
+
*/
|
|
45
50
|
levelBased?: {
|
|
51
|
+
/** Canonical level total configured on the platform at upload. */
|
|
46
52
|
levelCount: number;
|
|
47
|
-
/**
|
|
48
|
-
* Score-derived level progression for this player. Platform-owned and kept
|
|
49
|
-
* fully separate from `gameState` — never read progression out of gameState.
|
|
50
|
-
*/
|
|
53
|
+
/** Score-derived, platform-owned progression — never read from gameState. */
|
|
51
54
|
progress: LevelProgressState;
|
|
52
55
|
};
|
|
53
56
|
};
|
|
57
|
+
type LevelStars = 1 | 2 | 3;
|
|
58
|
+
/** Stars for one level attempt: 0 = failed, 1–3 = completed with that rating. */
|
|
59
|
+
type LevelAttemptStars = 0 | LevelStars;
|
|
60
|
+
/**
|
|
61
|
+
* One level attempt reported with game_over. Games report only what happened
|
|
62
|
+
* in the attempt; the host owns and derives all cumulative progression.
|
|
63
|
+
*/
|
|
64
|
+
type LevelAttempt = {
|
|
65
|
+
/** 1-based index of the level that was just played. */
|
|
66
|
+
levelIndex: number;
|
|
67
|
+
/** Stars earned this attempt; 0 means the level was failed. */
|
|
68
|
+
stars: LevelAttemptStars;
|
|
69
|
+
};
|
|
54
70
|
/** Score-derived, platform-owned progression for a level-based game. */
|
|
55
71
|
type LevelProgressState = {
|
|
56
72
|
currentLevelIndex: number;
|
|
@@ -59,9 +75,7 @@ type LevelProgressState = {
|
|
|
59
75
|
};
|
|
60
76
|
type ReadyEvent = {
|
|
61
77
|
type: 'ready';
|
|
62
|
-
data:
|
|
63
|
-
instanceId: string;
|
|
64
|
-
} | undefined;
|
|
78
|
+
data: undefined;
|
|
65
79
|
};
|
|
66
80
|
type PlayAgainEvent = {
|
|
67
81
|
type: 'play_again';
|
|
@@ -69,20 +83,6 @@ type PlayAgainEvent = {
|
|
|
69
83
|
levelIndex?: number;
|
|
70
84
|
};
|
|
71
85
|
};
|
|
72
|
-
type LevelStars = 1 | 2 | 3;
|
|
73
|
-
type LevelOutcome = 'level_complete' | 'level_failed' | 'all_complete';
|
|
74
|
-
/**
|
|
75
|
-
* One level attempt reported with game_over. Games report only what happened
|
|
76
|
-
* in the attempt; the host owns and derives all cumulative progression
|
|
77
|
-
* (star maps, unlock state) — see `LevelProgressState` for the host→game snapshot.
|
|
78
|
-
*/
|
|
79
|
-
type LevelAttempt = {
|
|
80
|
-
/** 1-based index of the level that was just played. */
|
|
81
|
-
levelIndex: number;
|
|
82
|
-
/** Stars earned this attempt. Omit for star-less games; a completion counts as 1. */
|
|
83
|
-
stars?: LevelStars;
|
|
84
|
-
outcome: LevelOutcome;
|
|
85
|
-
};
|
|
86
86
|
type SinglePlayerGameOverEvent = {
|
|
87
87
|
type: 'game_over';
|
|
88
88
|
data: {
|
|
@@ -120,7 +120,6 @@ type GameErrorEvent = {
|
|
|
120
120
|
lineno?: number;
|
|
121
121
|
colno?: number;
|
|
122
122
|
error?: Error;
|
|
123
|
-
stack?: string;
|
|
124
123
|
};
|
|
125
124
|
};
|
|
126
125
|
type GameInfoEvent = {
|
|
@@ -173,56 +172,41 @@ type GameEventMessage<T extends GameEvent['type']> = {
|
|
|
173
172
|
type: T;
|
|
174
173
|
}>;
|
|
175
174
|
};
|
|
176
|
-
/**
|
|
177
|
-
* Build a game_event envelope for sending over postMessage. Hosts and the SDK
|
|
178
|
-
* share this so the wire format is defined in one place.
|
|
179
|
-
*/
|
|
180
|
-
declare const createGameEventMessage: <T extends GameEvent["type"]>(type: T, data: Extract<GameEvent, {
|
|
181
|
-
type: T;
|
|
182
|
-
}>["data"]) => GameEventMessage<T>;
|
|
183
|
-
/**
|
|
184
|
-
* Parse an unknown postMessage payload into a GameEvent, or null when the
|
|
185
|
-
* payload is not a well-formed game_event envelope.
|
|
186
|
-
*/
|
|
187
|
-
declare const parseGameEventMessage: (value: unknown) => GameEvent | null;
|
|
188
175
|
/**
|
|
189
176
|
* Messages from the game host to the game client
|
|
190
177
|
*/
|
|
191
178
|
type IncomingGameEvent = GameEventMessage<'play_again' | 'toggle_mute' | 'game_info' | 'game_state_updated' | 'purchase_complete'>;
|
|
192
179
|
type OutgoingGameEvent = GameEventMessage<'game_over' | 'ready' | 'haptic_feedback' | 'error' | 'save_game_state' | 'refute_game_state' | 'multiplayer_game_over' | 'multiplayer_save_game_state' | 'purchase'>;
|
|
193
|
-
type
|
|
194
|
-
type IncomingGameEventData<T extends IncomingGameEventType> = Extract<GameEvent, {
|
|
195
|
-
type: T;
|
|
196
|
-
}>['data'];
|
|
180
|
+
type EventCallback = (data: unknown) => void;
|
|
197
181
|
declare class RemixSDK {
|
|
182
|
+
/**
|
|
183
|
+
* The published version of this bundle. The host compares it against the
|
|
184
|
+
* version it asked the browser to load, so a cached bundle from a previous
|
|
185
|
+
* release can be detected before any game code runs.
|
|
186
|
+
*/
|
|
187
|
+
readonly version: string;
|
|
198
188
|
private isClient;
|
|
199
189
|
private target;
|
|
200
190
|
private eventListeners;
|
|
201
|
-
private readyPromise;
|
|
202
191
|
private readyPromiseResolve;
|
|
203
|
-
private
|
|
204
|
-
private readyResendTimer;
|
|
205
|
-
private readonly instanceId;
|
|
192
|
+
private purchasePromiseResolve;
|
|
206
193
|
private _gameInfo?;
|
|
207
194
|
private _gameState?;
|
|
208
|
-
private _levelStars;
|
|
209
195
|
constructor();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
on<T extends IncomingGameEventType>(eventType: T, callback: (data: IncomingGameEventData<T>) => void): () => void;
|
|
213
|
-
off<T extends IncomingGameEventType>(eventType: T, callback: (data: IncomingGameEventData<T>) => void): void;
|
|
196
|
+
on(eventType: IncomingGameEvent['event']['type'], callback: EventCallback): void;
|
|
197
|
+
off(eventType: IncomingGameEvent['event']['type'], callback: EventCallback): void;
|
|
214
198
|
/**
|
|
215
199
|
* Listen for the host starting play: a replay after game over, or — for level
|
|
216
|
-
* games — a host-directed level via `data.levelIndex`
|
|
217
|
-
*
|
|
200
|
+
* games — a host-directed level via `data.levelIndex`. `data` may be omitted
|
|
201
|
+
* for a plain restart.
|
|
218
202
|
*/
|
|
219
|
-
onPlay(callback: (data?: PlayAgainEvent['data']) => void):
|
|
220
|
-
/**
|
|
221
|
-
onPlayAgain(callback: (data?: PlayAgainEvent['data']) => void):
|
|
222
|
-
onToggleMute(callback: (data: ToggleMuteEvent['data']) => void):
|
|
223
|
-
onGameStateUpdated(callback: (data: GameStateUpdatedEvent['data']) => void):
|
|
224
|
-
onGameInfo(callback: (data: GameInfoEvent['data']) => void):
|
|
225
|
-
onPurchaseComplete(callback: (data: PurchaseCompleteEvent['data']) => void):
|
|
203
|
+
onPlay(callback: (data?: PlayAgainEvent['data']) => void): void;
|
|
204
|
+
/** Alias of {@link onPlay}. */
|
|
205
|
+
onPlayAgain(callback: (data?: PlayAgainEvent['data']) => void): void;
|
|
206
|
+
onToggleMute(callback: (data: ToggleMuteEvent['data']) => void): void;
|
|
207
|
+
onGameStateUpdated(callback: (data: GameStateUpdatedEvent['data']) => void): void;
|
|
208
|
+
onGameInfo(callback: (data: GameInfoEvent['data']) => void): void;
|
|
209
|
+
onPurchaseComplete(callback: (data: PurchaseCompleteEvent['data']) => void): void;
|
|
226
210
|
setTarget(target: Window): void;
|
|
227
211
|
get purchasedItems(): string[];
|
|
228
212
|
get inventory(): InventoryItem[];
|
|
@@ -238,7 +222,7 @@ declare class RemixSDK {
|
|
|
238
222
|
get levelCount(): number | undefined;
|
|
239
223
|
/** 1-based level index from score-derived progression, defaulting to 1. */
|
|
240
224
|
get currentLevelIndex(): number;
|
|
241
|
-
/** Best stars
|
|
225
|
+
/** Best stars per level from score-derived progression. Keys are 1-based level indices. */
|
|
242
226
|
get levelStars(): Record<string, LevelStars>;
|
|
243
227
|
/** Highest unlocked level from score-derived progression, defaulting to 1. */
|
|
244
228
|
get highestUnlockedLevel(): number;
|
|
@@ -281,4 +265,4 @@ declare class RemixSDK {
|
|
|
281
265
|
}
|
|
282
266
|
declare const sdk: RemixSDK;
|
|
283
267
|
|
|
284
|
-
export { type GameErrorEvent, type GameEvent, type GameEventMessage, type GameInfo, type GameInfoEvent, type GameState, type GameStateUpdatedEvent, type HapticFeedbackEvent, type HapticFeedbackType, type IncomingGameEvent, type
|
|
268
|
+
export { type GameErrorEvent, type GameEvent, type GameEventMessage, type GameInfo, type GameInfoEvent, type GameState, type GameStateUpdatedEvent, type HapticFeedbackEvent, type HapticFeedbackType, type IncomingGameEvent, type InventoryItem, type LevelAttempt, type LevelAttemptStars, type LevelProgressState, type LevelStars, type MultiplayerGameOverEvent, type MultiplayerSaveGameStateEvent, type OutgoingGameEvent, type PlayAgainEvent, type Player, type PurchaseCompleteEvent, type PurchaseEvent, type ReadyEvent, type RefuteGameStateEvent, RemixSDK, type SafeAreaInset, type SaveGameStateEvent, type ShopItem, type SinglePlayerGameOverEvent, type ToggleMuteEvent, type ViewContext, ZERO_SAFE_AREA_INSET, sdk };
|
package/dist/index.d.ts
CHANGED
|
@@ -42,15 +42,31 @@ type GameInfo = {
|
|
|
42
42
|
id: string;
|
|
43
43
|
gameState: GameState;
|
|
44
44
|
} | null;
|
|
45
|
+
/**
|
|
46
|
+
* Present only when the host has level progression enabled for this session.
|
|
47
|
+
* Games must key level mode off this block's presence, not their own level
|
|
48
|
+
* content — the platform can disable it (e.g. feature gating) at any time.
|
|
49
|
+
*/
|
|
45
50
|
levelBased?: {
|
|
51
|
+
/** Canonical level total configured on the platform at upload. */
|
|
46
52
|
levelCount: number;
|
|
47
|
-
/**
|
|
48
|
-
* Score-derived level progression for this player. Platform-owned and kept
|
|
49
|
-
* fully separate from `gameState` — never read progression out of gameState.
|
|
50
|
-
*/
|
|
53
|
+
/** Score-derived, platform-owned progression — never read from gameState. */
|
|
51
54
|
progress: LevelProgressState;
|
|
52
55
|
};
|
|
53
56
|
};
|
|
57
|
+
type LevelStars = 1 | 2 | 3;
|
|
58
|
+
/** Stars for one level attempt: 0 = failed, 1–3 = completed with that rating. */
|
|
59
|
+
type LevelAttemptStars = 0 | LevelStars;
|
|
60
|
+
/**
|
|
61
|
+
* One level attempt reported with game_over. Games report only what happened
|
|
62
|
+
* in the attempt; the host owns and derives all cumulative progression.
|
|
63
|
+
*/
|
|
64
|
+
type LevelAttempt = {
|
|
65
|
+
/** 1-based index of the level that was just played. */
|
|
66
|
+
levelIndex: number;
|
|
67
|
+
/** Stars earned this attempt; 0 means the level was failed. */
|
|
68
|
+
stars: LevelAttemptStars;
|
|
69
|
+
};
|
|
54
70
|
/** Score-derived, platform-owned progression for a level-based game. */
|
|
55
71
|
type LevelProgressState = {
|
|
56
72
|
currentLevelIndex: number;
|
|
@@ -59,9 +75,7 @@ type LevelProgressState = {
|
|
|
59
75
|
};
|
|
60
76
|
type ReadyEvent = {
|
|
61
77
|
type: 'ready';
|
|
62
|
-
data:
|
|
63
|
-
instanceId: string;
|
|
64
|
-
} | undefined;
|
|
78
|
+
data: undefined;
|
|
65
79
|
};
|
|
66
80
|
type PlayAgainEvent = {
|
|
67
81
|
type: 'play_again';
|
|
@@ -69,20 +83,6 @@ type PlayAgainEvent = {
|
|
|
69
83
|
levelIndex?: number;
|
|
70
84
|
};
|
|
71
85
|
};
|
|
72
|
-
type LevelStars = 1 | 2 | 3;
|
|
73
|
-
type LevelOutcome = 'level_complete' | 'level_failed' | 'all_complete';
|
|
74
|
-
/**
|
|
75
|
-
* One level attempt reported with game_over. Games report only what happened
|
|
76
|
-
* in the attempt; the host owns and derives all cumulative progression
|
|
77
|
-
* (star maps, unlock state) — see `LevelProgressState` for the host→game snapshot.
|
|
78
|
-
*/
|
|
79
|
-
type LevelAttempt = {
|
|
80
|
-
/** 1-based index of the level that was just played. */
|
|
81
|
-
levelIndex: number;
|
|
82
|
-
/** Stars earned this attempt. Omit for star-less games; a completion counts as 1. */
|
|
83
|
-
stars?: LevelStars;
|
|
84
|
-
outcome: LevelOutcome;
|
|
85
|
-
};
|
|
86
86
|
type SinglePlayerGameOverEvent = {
|
|
87
87
|
type: 'game_over';
|
|
88
88
|
data: {
|
|
@@ -120,7 +120,6 @@ type GameErrorEvent = {
|
|
|
120
120
|
lineno?: number;
|
|
121
121
|
colno?: number;
|
|
122
122
|
error?: Error;
|
|
123
|
-
stack?: string;
|
|
124
123
|
};
|
|
125
124
|
};
|
|
126
125
|
type GameInfoEvent = {
|
|
@@ -173,56 +172,41 @@ type GameEventMessage<T extends GameEvent['type']> = {
|
|
|
173
172
|
type: T;
|
|
174
173
|
}>;
|
|
175
174
|
};
|
|
176
|
-
/**
|
|
177
|
-
* Build a game_event envelope for sending over postMessage. Hosts and the SDK
|
|
178
|
-
* share this so the wire format is defined in one place.
|
|
179
|
-
*/
|
|
180
|
-
declare const createGameEventMessage: <T extends GameEvent["type"]>(type: T, data: Extract<GameEvent, {
|
|
181
|
-
type: T;
|
|
182
|
-
}>["data"]) => GameEventMessage<T>;
|
|
183
|
-
/**
|
|
184
|
-
* Parse an unknown postMessage payload into a GameEvent, or null when the
|
|
185
|
-
* payload is not a well-formed game_event envelope.
|
|
186
|
-
*/
|
|
187
|
-
declare const parseGameEventMessage: (value: unknown) => GameEvent | null;
|
|
188
175
|
/**
|
|
189
176
|
* Messages from the game host to the game client
|
|
190
177
|
*/
|
|
191
178
|
type IncomingGameEvent = GameEventMessage<'play_again' | 'toggle_mute' | 'game_info' | 'game_state_updated' | 'purchase_complete'>;
|
|
192
179
|
type OutgoingGameEvent = GameEventMessage<'game_over' | 'ready' | 'haptic_feedback' | 'error' | 'save_game_state' | 'refute_game_state' | 'multiplayer_game_over' | 'multiplayer_save_game_state' | 'purchase'>;
|
|
193
|
-
type
|
|
194
|
-
type IncomingGameEventData<T extends IncomingGameEventType> = Extract<GameEvent, {
|
|
195
|
-
type: T;
|
|
196
|
-
}>['data'];
|
|
180
|
+
type EventCallback = (data: unknown) => void;
|
|
197
181
|
declare class RemixSDK {
|
|
182
|
+
/**
|
|
183
|
+
* The published version of this bundle. The host compares it against the
|
|
184
|
+
* version it asked the browser to load, so a cached bundle from a previous
|
|
185
|
+
* release can be detected before any game code runs.
|
|
186
|
+
*/
|
|
187
|
+
readonly version: string;
|
|
198
188
|
private isClient;
|
|
199
189
|
private target;
|
|
200
190
|
private eventListeners;
|
|
201
|
-
private readyPromise;
|
|
202
191
|
private readyPromiseResolve;
|
|
203
|
-
private
|
|
204
|
-
private readyResendTimer;
|
|
205
|
-
private readonly instanceId;
|
|
192
|
+
private purchasePromiseResolve;
|
|
206
193
|
private _gameInfo?;
|
|
207
194
|
private _gameState?;
|
|
208
|
-
private _levelStars;
|
|
209
195
|
constructor();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
on<T extends IncomingGameEventType>(eventType: T, callback: (data: IncomingGameEventData<T>) => void): () => void;
|
|
213
|
-
off<T extends IncomingGameEventType>(eventType: T, callback: (data: IncomingGameEventData<T>) => void): void;
|
|
196
|
+
on(eventType: IncomingGameEvent['event']['type'], callback: EventCallback): void;
|
|
197
|
+
off(eventType: IncomingGameEvent['event']['type'], callback: EventCallback): void;
|
|
214
198
|
/**
|
|
215
199
|
* Listen for the host starting play: a replay after game over, or — for level
|
|
216
|
-
* games — a host-directed level via `data.levelIndex`
|
|
217
|
-
*
|
|
200
|
+
* games — a host-directed level via `data.levelIndex`. `data` may be omitted
|
|
201
|
+
* for a plain restart.
|
|
218
202
|
*/
|
|
219
|
-
onPlay(callback: (data?: PlayAgainEvent['data']) => void):
|
|
220
|
-
/**
|
|
221
|
-
onPlayAgain(callback: (data?: PlayAgainEvent['data']) => void):
|
|
222
|
-
onToggleMute(callback: (data: ToggleMuteEvent['data']) => void):
|
|
223
|
-
onGameStateUpdated(callback: (data: GameStateUpdatedEvent['data']) => void):
|
|
224
|
-
onGameInfo(callback: (data: GameInfoEvent['data']) => void):
|
|
225
|
-
onPurchaseComplete(callback: (data: PurchaseCompleteEvent['data']) => void):
|
|
203
|
+
onPlay(callback: (data?: PlayAgainEvent['data']) => void): void;
|
|
204
|
+
/** Alias of {@link onPlay}. */
|
|
205
|
+
onPlayAgain(callback: (data?: PlayAgainEvent['data']) => void): void;
|
|
206
|
+
onToggleMute(callback: (data: ToggleMuteEvent['data']) => void): void;
|
|
207
|
+
onGameStateUpdated(callback: (data: GameStateUpdatedEvent['data']) => void): void;
|
|
208
|
+
onGameInfo(callback: (data: GameInfoEvent['data']) => void): void;
|
|
209
|
+
onPurchaseComplete(callback: (data: PurchaseCompleteEvent['data']) => void): void;
|
|
226
210
|
setTarget(target: Window): void;
|
|
227
211
|
get purchasedItems(): string[];
|
|
228
212
|
get inventory(): InventoryItem[];
|
|
@@ -238,7 +222,7 @@ declare class RemixSDK {
|
|
|
238
222
|
get levelCount(): number | undefined;
|
|
239
223
|
/** 1-based level index from score-derived progression, defaulting to 1. */
|
|
240
224
|
get currentLevelIndex(): number;
|
|
241
|
-
/** Best stars
|
|
225
|
+
/** Best stars per level from score-derived progression. Keys are 1-based level indices. */
|
|
242
226
|
get levelStars(): Record<string, LevelStars>;
|
|
243
227
|
/** Highest unlocked level from score-derived progression, defaulting to 1. */
|
|
244
228
|
get highestUnlockedLevel(): number;
|
|
@@ -281,4 +265,4 @@ declare class RemixSDK {
|
|
|
281
265
|
}
|
|
282
266
|
declare const sdk: RemixSDK;
|
|
283
267
|
|
|
284
|
-
export { type GameErrorEvent, type GameEvent, type GameEventMessage, type GameInfo, type GameInfoEvent, type GameState, type GameStateUpdatedEvent, type HapticFeedbackEvent, type HapticFeedbackType, type IncomingGameEvent, type
|
|
268
|
+
export { type GameErrorEvent, type GameEvent, type GameEventMessage, type GameInfo, type GameInfoEvent, type GameState, type GameStateUpdatedEvent, type HapticFeedbackEvent, type HapticFeedbackType, type IncomingGameEvent, type InventoryItem, type LevelAttempt, type LevelAttemptStars, type LevelProgressState, type LevelStars, type MultiplayerGameOverEvent, type MultiplayerSaveGameStateEvent, type OutgoingGameEvent, type PlayAgainEvent, type Player, type PurchaseCompleteEvent, type PurchaseEvent, type ReadyEvent, type RefuteGameStateEvent, RemixSDK, type SafeAreaInset, type SaveGameStateEvent, type ShopItem, type SinglePlayerGameOverEvent, type ToggleMuteEvent, type ViewContext, ZERO_SAFE_AREA_INSET, sdk };
|
package/dist/index.js
CHANGED
|
@@ -39,62 +39,40 @@ var src_exports = {};
|
|
|
39
39
|
__export(src_exports, {
|
|
40
40
|
RemixSDK: () => RemixSDK,
|
|
41
41
|
ZERO_SAFE_AREA_INSET: () => ZERO_SAFE_AREA_INSET,
|
|
42
|
-
createGameEventMessage: () => createGameEventMessage,
|
|
43
|
-
parseGameEventMessage: () => parseGameEventMessage,
|
|
44
42
|
sdk: () => sdk
|
|
45
43
|
});
|
|
46
44
|
module.exports = __toCommonJS(src_exports);
|
|
47
|
-
var ZERO_SAFE_AREA_INSET =
|
|
45
|
+
var ZERO_SAFE_AREA_INSET = {
|
|
48
46
|
top: 0,
|
|
49
47
|
right: 0,
|
|
50
48
|
bottom: 0,
|
|
51
49
|
left: 0
|
|
52
|
-
});
|
|
53
|
-
var createGameEventMessage = (type, data) => {
|
|
54
|
-
return { type: "game_event", event: { type, data } };
|
|
55
|
-
};
|
|
56
|
-
var parseGameEventMessage = (value) => {
|
|
57
|
-
if (typeof value !== "object" || value === null)
|
|
58
|
-
return null;
|
|
59
|
-
const message = value;
|
|
60
|
-
if (message.type !== "game_event")
|
|
61
|
-
return null;
|
|
62
|
-
const event = message.event;
|
|
63
|
-
if (typeof event !== "object" || event === null)
|
|
64
|
-
return null;
|
|
65
|
-
if (typeof event.type !== "string")
|
|
66
|
-
return null;
|
|
67
|
-
return event;
|
|
68
50
|
};
|
|
69
|
-
var
|
|
70
|
-
var READY_RESEND_MAX_ATTEMPTS = 5;
|
|
71
|
-
var generateInstanceId = () => typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2);
|
|
72
|
-
var isBrowserGameClient = () => typeof window !== "undefined" && typeof window.addEventListener === "function" && typeof window.removeEventListener === "function";
|
|
51
|
+
var SDK_VERSION = true ? "0.8.1" : UNKNOWN_SDK_VERSION;
|
|
73
52
|
var RemixSDK = class {
|
|
74
53
|
constructor() {
|
|
54
|
+
/**
|
|
55
|
+
* The published version of this bundle. The host compares it against the
|
|
56
|
+
* version it asked the browser to load, so a cached bundle from a previous
|
|
57
|
+
* release can be detected before any game code runs.
|
|
58
|
+
*/
|
|
59
|
+
this.version = SDK_VERSION;
|
|
75
60
|
this.target = null;
|
|
76
61
|
this.eventListeners = /* @__PURE__ */ new Map();
|
|
77
|
-
this.readyPromise = null;
|
|
78
62
|
this.readyPromiseResolve = null;
|
|
79
|
-
this.
|
|
80
|
-
this.readyResendTimer = null;
|
|
81
|
-
this.instanceId = generateInstanceId();
|
|
82
|
-
this._levelStars = Object.freeze({});
|
|
63
|
+
this.purchasePromiseResolve = null;
|
|
83
64
|
this.ready = () => {
|
|
84
65
|
if (this._gameInfo) {
|
|
85
66
|
return Promise.resolve(this._gameInfo);
|
|
86
67
|
}
|
|
87
|
-
|
|
88
|
-
this.
|
|
89
|
-
|
|
90
|
-
});
|
|
91
|
-
}
|
|
92
|
-
return this.readyPromise;
|
|
68
|
+
return new Promise((resolve) => {
|
|
69
|
+
this.readyPromiseResolve = resolve;
|
|
70
|
+
});
|
|
93
71
|
};
|
|
94
72
|
this.purchase = (data) => {
|
|
95
73
|
this.sendMessage("purchase", data);
|
|
96
74
|
return new Promise((resolve) => {
|
|
97
|
-
this.
|
|
75
|
+
this.purchasePromiseResolve = resolve;
|
|
98
76
|
});
|
|
99
77
|
};
|
|
100
78
|
this.reportError = (data) => {
|
|
@@ -141,12 +119,10 @@ var RemixSDK = class {
|
|
|
141
119
|
})
|
|
142
120
|
};
|
|
143
121
|
this.handleMessage = (event) => {
|
|
144
|
-
|
|
122
|
+
var _a;
|
|
123
|
+
if (((_a = event.data) == null ? void 0 : _a.type) !== "game_event")
|
|
145
124
|
return;
|
|
146
|
-
|
|
147
|
-
if (!gameEvent)
|
|
148
|
-
return;
|
|
149
|
-
this.emit(gameEvent.type, gameEvent.data);
|
|
125
|
+
this.emit(event.data.event.type, event.data.event.data);
|
|
150
126
|
};
|
|
151
127
|
this.sendMessage = (type, data) => {
|
|
152
128
|
if (!this.isClient || !this.target)
|
|
@@ -160,45 +136,23 @@ var RemixSDK = class {
|
|
|
160
136
|
source: event.filename,
|
|
161
137
|
lineno: event.lineno,
|
|
162
138
|
colno: event.colno,
|
|
163
|
-
error: event.error
|
|
164
|
-
stack: event.error instanceof Error ? event.error.stack : void 0
|
|
139
|
+
error: event.error
|
|
165
140
|
});
|
|
166
141
|
};
|
|
167
142
|
this.handleUnhandledRejection = (event) => {
|
|
168
143
|
const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
|
|
169
144
|
this.sendMessage("error", {
|
|
170
145
|
message: error.message,
|
|
171
|
-
error
|
|
172
|
-
stack: error.stack
|
|
146
|
+
error
|
|
173
147
|
});
|
|
174
148
|
};
|
|
175
|
-
this.isClient =
|
|
149
|
+
this.isClient = typeof window !== "undefined";
|
|
176
150
|
this.target = this.isClient ? window.parent : null;
|
|
177
151
|
if (this.isClient) {
|
|
178
152
|
window.addEventListener("message", this.handleMessage);
|
|
179
153
|
window.addEventListener("error", this.handleGlobalError);
|
|
180
154
|
window.addEventListener("unhandledrejection", this.handleUnhandledRejection);
|
|
181
|
-
this.sendMessage("ready",
|
|
182
|
-
this.scheduleReadyResend(1);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
scheduleReadyResend(attempt) {
|
|
186
|
-
if (attempt > READY_RESEND_MAX_ATTEMPTS)
|
|
187
|
-
return;
|
|
188
|
-
this.readyResendTimer = setTimeout(
|
|
189
|
-
() => {
|
|
190
|
-
if (this._gameInfo)
|
|
191
|
-
return;
|
|
192
|
-
this.sendMessage("ready", { instanceId: this.instanceId });
|
|
193
|
-
this.scheduleReadyResend(attempt + 1);
|
|
194
|
-
},
|
|
195
|
-
READY_RESEND_INITIAL_DELAY_MS * 2 ** (attempt - 1)
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
cancelReadyResend() {
|
|
199
|
-
if (this.readyResendTimer !== null) {
|
|
200
|
-
clearTimeout(this.readyResendTimer);
|
|
201
|
-
this.readyResendTimer = null;
|
|
155
|
+
this.sendMessage("ready", void 0);
|
|
202
156
|
}
|
|
203
157
|
}
|
|
204
158
|
on(eventType, callback) {
|
|
@@ -207,37 +161,35 @@ var RemixSDK = class {
|
|
|
207
161
|
this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
|
|
208
162
|
}
|
|
209
163
|
(_a = this.eventListeners.get(eventType)) == null ? void 0 : _a.add(callback);
|
|
210
|
-
return () => this.off(eventType, callback);
|
|
211
164
|
}
|
|
212
165
|
off(eventType, callback) {
|
|
213
166
|
var _a;
|
|
214
167
|
(_a = this.eventListeners.get(eventType)) == null ? void 0 : _a.delete(callback);
|
|
215
168
|
}
|
|
216
|
-
// explicitly named event listeners for better understanding and type safety
|
|
217
|
-
// each returns an unsubscribe function
|
|
169
|
+
// explicitly named event listeners for better understanding and type safety
|
|
218
170
|
/**
|
|
219
171
|
* Listen for the host starting play: a replay after game over, or — for level
|
|
220
|
-
* games — a host-directed level via `data.levelIndex`
|
|
221
|
-
*
|
|
172
|
+
* games — a host-directed level via `data.levelIndex`. `data` may be omitted
|
|
173
|
+
* for a plain restart.
|
|
222
174
|
*/
|
|
223
175
|
onPlay(callback) {
|
|
224
|
-
|
|
176
|
+
this.on("play_again", (data) => callback(data));
|
|
225
177
|
}
|
|
226
|
-
/**
|
|
178
|
+
/** Alias of {@link onPlay}. */
|
|
227
179
|
onPlayAgain(callback) {
|
|
228
|
-
|
|
180
|
+
this.onPlay(callback);
|
|
229
181
|
}
|
|
230
182
|
onToggleMute(callback) {
|
|
231
|
-
|
|
183
|
+
this.on("toggle_mute", (data) => callback(data));
|
|
232
184
|
}
|
|
233
185
|
onGameStateUpdated(callback) {
|
|
234
|
-
|
|
186
|
+
this.on("game_state_updated", (data) => callback(data));
|
|
235
187
|
}
|
|
236
188
|
onGameInfo(callback) {
|
|
237
|
-
|
|
189
|
+
this.on("game_info", (data) => callback(data));
|
|
238
190
|
}
|
|
239
191
|
onPurchaseComplete(callback) {
|
|
240
|
-
|
|
192
|
+
this.on("purchase_complete", (data) => callback(data));
|
|
241
193
|
}
|
|
242
194
|
// end of explicitly named event listeners
|
|
243
195
|
setTarget(target) {
|
|
@@ -293,9 +245,18 @@ var RemixSDK = class {
|
|
|
293
245
|
const value = (_c = (_b = (_a = this._gameInfo) == null ? void 0 : _a.levelBased) == null ? void 0 : _b.progress) == null ? void 0 : _c.currentLevelIndex;
|
|
294
246
|
return typeof value === "number" && Number.isFinite(value) && value >= 1 ? value : 1;
|
|
295
247
|
}
|
|
296
|
-
/** Best stars
|
|
248
|
+
/** Best stars per level from score-derived progression. Keys are 1-based level indices. */
|
|
297
249
|
get levelStars() {
|
|
298
|
-
|
|
250
|
+
var _a, _b, _c;
|
|
251
|
+
const raw = (_c = (_b = (_a = this._gameInfo) == null ? void 0 : _a.levelBased) == null ? void 0 : _b.progress) == null ? void 0 : _c.levelStars;
|
|
252
|
+
const levelStars = {};
|
|
253
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) {
|
|
254
|
+
for (const [key, starValue] of Object.entries(raw)) {
|
|
255
|
+
if (starValue === 1 || starValue === 2 || starValue === 3)
|
|
256
|
+
levelStars[key] = starValue;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return levelStars;
|
|
299
260
|
}
|
|
300
261
|
/** Highest unlocked level from score-derived progression, defaulting to 1. */
|
|
301
262
|
get highestUnlockedLevel() {
|
|
@@ -308,20 +269,10 @@ var RemixSDK = class {
|
|
|
308
269
|
return Object.values(this.levelStars).reduce((sum, stars) => sum + stars, 0);
|
|
309
270
|
}
|
|
310
271
|
emit(eventType, data) {
|
|
311
|
-
var _a
|
|
272
|
+
var _a;
|
|
312
273
|
if (eventType === "game_info") {
|
|
313
274
|
const eventData = data;
|
|
314
275
|
this._gameInfo = eventData;
|
|
315
|
-
const rawLevelStars = (_b = (_a = eventData.levelBased) == null ? void 0 : _a.progress) == null ? void 0 : _b.levelStars;
|
|
316
|
-
const levelStars = {};
|
|
317
|
-
if (rawLevelStars && typeof rawLevelStars === "object" && !Array.isArray(rawLevelStars)) {
|
|
318
|
-
for (const [key, starValue] of Object.entries(rawLevelStars)) {
|
|
319
|
-
if (starValue === 1 || starValue === 2 || starValue === 3)
|
|
320
|
-
levelStars[key] = starValue;
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
this._levelStars = Object.freeze(levelStars);
|
|
324
|
-
this.cancelReadyResend();
|
|
325
276
|
if (!this._gameState && eventData.initialGameState) {
|
|
326
277
|
this._gameState = eventData.initialGameState.gameState;
|
|
327
278
|
}
|
|
@@ -332,12 +283,12 @@ var RemixSDK = class {
|
|
|
332
283
|
}
|
|
333
284
|
if (eventType === "purchase_complete") {
|
|
334
285
|
const eventData = data;
|
|
335
|
-
if (eventData.success && eventData.item && ((
|
|
286
|
+
if (eventData.success && eventData.item && ((_a = this._gameInfo) == null ? void 0 : _a.player)) {
|
|
336
287
|
this.applyPurchaseToCurrentPlayer(eventData.item);
|
|
337
288
|
}
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
289
|
+
if (this.purchasePromiseResolve) {
|
|
290
|
+
this.purchasePromiseResolve(eventData);
|
|
291
|
+
this.purchasePromiseResolve = null;
|
|
341
292
|
}
|
|
342
293
|
}
|
|
343
294
|
if (eventType === "game_state_updated") {
|
|
@@ -357,15 +308,17 @@ var RemixSDK = class {
|
|
|
357
308
|
return;
|
|
358
309
|
const currentPlayer = this._gameInfo.player;
|
|
359
310
|
currentPlayer.purchasedItems = [...currentPlayer.purchasedItems, item];
|
|
360
|
-
|
|
361
|
-
if (player
|
|
362
|
-
player
|
|
363
|
-
}
|
|
364
|
-
|
|
311
|
+
this._gameInfo.players = this._gameInfo.players.map((player) => {
|
|
312
|
+
if (player.id !== currentPlayer.id)
|
|
313
|
+
return player;
|
|
314
|
+
return __spreadProps(__spreadValues({}, player), {
|
|
315
|
+
purchasedItems: currentPlayer.purchasedItems
|
|
316
|
+
});
|
|
317
|
+
});
|
|
365
318
|
}
|
|
366
319
|
};
|
|
367
320
|
var sdk = new RemixSDK();
|
|
368
|
-
if (
|
|
321
|
+
if (typeof window !== "undefined") {
|
|
369
322
|
window.FarcadeSDK = sdk;
|
|
370
323
|
window.RemixSDK = sdk;
|
|
371
324
|
}
|
|
@@ -373,7 +326,5 @@ if (isBrowserGameClient()) {
|
|
|
373
326
|
0 && (module.exports = {
|
|
374
327
|
RemixSDK,
|
|
375
328
|
ZERO_SAFE_AREA_INSET,
|
|
376
|
-
createGameEventMessage,
|
|
377
|
-
parseGameEventMessage,
|
|
378
329
|
sdk
|
|
379
330
|
});
|