@remix-gg/sdk 0.7.0 → 0.8.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.js CHANGED
@@ -1,119 +1,150 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __defProps = Object.defineProperties;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
10
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
11
- var __spreadValues = (a, b) => {
12
- for (var prop in b || (b = {}))
13
- if (__hasOwnProp.call(b, prop))
14
- __defNormalProp(a, prop, b[prop]);
15
- if (__getOwnPropSymbols)
16
- for (var prop of __getOwnPropSymbols(b)) {
17
- if (__propIsEnum.call(b, prop))
18
- __defNormalProp(a, prop, b[prop]);
19
- }
20
- return a;
21
- };
22
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
23
- var __export = (target, all) => {
24
- for (var name in all)
25
- __defProp(target, name, { get: all[name], enumerable: true });
26
- };
27
- var __copyProps = (to, from, except, desc) => {
28
- if (from && typeof from === "object" || typeof from === "function") {
29
- for (let key of __getOwnPropNames(from))
30
- if (!__hasOwnProp.call(to, key) && key !== except)
31
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
32
- }
33
- return to;
34
- };
35
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
1
+ (() => {
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __moduleCache = /* @__PURE__ */ new WeakMap;
7
+ var __toCommonJS = (from) => {
8
+ var entry = __moduleCache.get(from), desc;
9
+ if (entry)
10
+ return entry;
11
+ entry = __defProp({}, "__esModule", { value: true });
12
+ if (from && typeof from === "object" || typeof from === "function")
13
+ __getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
14
+ get: () => from[key],
15
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
+ }));
17
+ __moduleCache.set(from, entry);
18
+ return entry;
19
+ };
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
36
29
 
37
- // src/index.ts
38
- var src_exports = {};
39
- __export(src_exports, {
40
- RemixSDK: () => RemixSDK,
41
- ZERO_SAFE_AREA_INSET: () => ZERO_SAFE_AREA_INSET,
42
- createGameEventMessage: () => createGameEventMessage,
43
- parseGameEventMessage: () => parseGameEventMessage,
44
- sdk: () => sdk
45
- });
46
- module.exports = __toCommonJS(src_exports);
47
- var ZERO_SAFE_AREA_INSET = Object.freeze({
48
- top: 0,
49
- right: 0,
50
- bottom: 0,
51
- 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
- };
69
- var READY_RESEND_INITIAL_DELAY_MS = 250;
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";
73
- var RemixSDK = class {
74
- constructor() {
75
- this.target = null;
76
- this.eventListeners = /* @__PURE__ */ new Map();
77
- this.readyPromise = null;
78
- this.readyPromiseResolve = null;
79
- this.purchasePromiseResolvers = [];
80
- this.readyResendTimer = null;
81
- this.instanceId = generateInstanceId();
82
- this._levelStars = Object.freeze({});
83
- this.ready = () => {
30
+ // src/index.ts
31
+ var exports_src = {};
32
+ __export(exports_src, {
33
+ sdk: () => sdk,
34
+ ZERO_SAFE_AREA_INSET: () => ZERO_SAFE_AREA_INSET,
35
+ RemixSDK: () => RemixSDK
36
+ });
37
+ var ZERO_SAFE_AREA_INSET = {
38
+ top: 0,
39
+ right: 0,
40
+ bottom: 0,
41
+ left: 0
42
+ };
43
+
44
+ class RemixSDK {
45
+ isClient;
46
+ target = null;
47
+ eventListeners = new Map;
48
+ readyPromiseResolve = null;
49
+ purchasePromiseResolve = null;
50
+ _gameInfo;
51
+ _gameState;
52
+ constructor() {
53
+ this.isClient = typeof window !== "undefined";
54
+ this.target = this.isClient ? window.parent : null;
55
+ if (this.isClient) {
56
+ window.addEventListener("message", this.handleMessage);
57
+ window.addEventListener("error", this.handleGlobalError);
58
+ window.addEventListener("unhandledrejection", this.handleUnhandledRejection);
59
+ this.sendMessage("ready", undefined);
60
+ }
61
+ }
62
+ on(eventType, callback) {
63
+ if (!this.eventListeners.has(eventType)) {
64
+ this.eventListeners.set(eventType, new Set);
65
+ }
66
+ this.eventListeners.get(eventType)?.add(callback);
67
+ }
68
+ off(eventType, callback) {
69
+ this.eventListeners.get(eventType)?.delete(callback);
70
+ }
71
+ onPlayAgain(callback) {
72
+ this.on("play_again", () => callback());
73
+ }
74
+ onToggleMute(callback) {
75
+ this.on("toggle_mute", (data) => callback(data));
76
+ }
77
+ onGameStateUpdated(callback) {
78
+ this.on("game_state_updated", (data) => callback(data));
79
+ }
80
+ onGameInfo(callback) {
81
+ this.on("game_info", (data) => callback(data));
82
+ }
83
+ onPurchaseComplete(callback) {
84
+ this.on("purchase_complete", (data) => callback(data));
85
+ }
86
+ setTarget(target) {
87
+ this.target = target;
88
+ }
89
+ get purchasedItems() {
90
+ return this._gameInfo?.player.purchasedItems || [];
91
+ }
92
+ get inventory() {
93
+ const counts = new Map;
94
+ for (const item of this.purchasedItems) {
95
+ counts.set(item, (counts.get(item) || 0) + 1);
96
+ }
97
+ return [...counts.entries()].map(([slug, quantity]) => ({ slug, quantity }));
98
+ }
99
+ get shopItems() {
100
+ return this._gameInfo?.shopItems || [];
101
+ }
102
+ get gameInfo() {
103
+ return this._gameInfo;
104
+ }
105
+ get gameState() {
106
+ return this._gameState;
107
+ }
108
+ get players() {
109
+ return this._gameInfo?.players;
110
+ }
111
+ get player() {
112
+ return this._gameInfo?.player;
113
+ }
114
+ get isReady() {
115
+ return !!this._gameInfo;
116
+ }
117
+ ready = () => {
84
118
  if (this._gameInfo) {
85
119
  return Promise.resolve(this._gameInfo);
86
120
  }
87
- if (!this.readyPromise) {
88
- this.readyPromise = new Promise((resolve) => {
89
- this.readyPromiseResolve = resolve;
90
- });
91
- }
92
- return this.readyPromise;
121
+ return new Promise((resolve) => {
122
+ this.readyPromiseResolve = resolve;
123
+ });
93
124
  };
94
- this.purchase = (data) => {
125
+ purchase = (data) => {
95
126
  this.sendMessage("purchase", data);
96
127
  return new Promise((resolve) => {
97
- this.purchasePromiseResolvers.push(resolve);
128
+ this.purchasePromiseResolve = resolve;
98
129
  });
99
130
  };
100
- this.reportError = (data) => {
131
+ reportError = (data) => {
101
132
  this.sendMessage("error", data);
102
133
  };
103
- this.hapticFeedback = (type) => {
104
- this.sendMessage("haptic_feedback", type ? { type } : void 0);
134
+ hapticFeedback = (type) => {
135
+ this.sendMessage("haptic_feedback", type ? { type } : undefined);
105
136
  };
106
- this.hasItem = (item) => {
137
+ hasItem = (item) => {
107
138
  return this.getItemPurchaseCount(item) > 0;
108
139
  };
109
- this.getItemPurchaseCount = (item) => {
140
+ getItemPurchaseCount = (item) => {
110
141
  const inventoryItem = this.inventory.find((entry) => entry.slug === item);
111
- return (inventoryItem == null ? void 0 : inventoryItem.quantity) || 0;
142
+ return inventoryItem?.quantity || 0;
112
143
  };
113
- this.getShopItem = (slug) => {
144
+ getShopItem = (slug) => {
114
145
  return this.shopItems.find((item) => item.slug === slug);
115
146
  };
116
- this.singlePlayer = {
147
+ singlePlayer = {
117
148
  actions: {
118
149
  ready: this.ready,
119
150
  hapticFeedback: this.hapticFeedback,
@@ -127,8 +158,9 @@ var RemixSDK = class {
127
158
  }
128
159
  }
129
160
  };
130
- this.multiplayer = {
131
- actions: __spreadProps(__spreadValues({}, this.singlePlayer.actions), {
161
+ multiplayer = {
162
+ actions: {
163
+ ...this.singlePlayer.actions,
132
164
  gameOver: (data) => {
133
165
  this.sendMessage("multiplayer_game_over", data);
134
166
  },
@@ -138,242 +170,89 @@ var RemixSDK = class {
138
170
  saveGameState: (data) => {
139
171
  this.sendMessage("multiplayer_save_game_state", data);
140
172
  }
141
- })
173
+ }
142
174
  };
143
- this.handleMessage = (event) => {
144
- if (event.source && event.source !== this.target)
145
- return;
146
- const gameEvent = parseGameEventMessage(event.data);
147
- if (!gameEvent)
175
+ emit(eventType, data) {
176
+ if (eventType === "game_info") {
177
+ const eventData = data;
178
+ this._gameInfo = eventData;
179
+ if (!this._gameState && eventData.initialGameState) {
180
+ this._gameState = eventData.initialGameState.gameState;
181
+ }
182
+ if (this.readyPromiseResolve) {
183
+ this.readyPromiseResolve(this._gameInfo);
184
+ this.readyPromiseResolve = null;
185
+ }
186
+ }
187
+ if (eventType === "purchase_complete") {
188
+ const eventData = data;
189
+ if (eventData.success && eventData.item && this._gameInfo?.player) {
190
+ this.applyPurchaseToCurrentPlayer(eventData.item);
191
+ }
192
+ if (this.purchasePromiseResolve) {
193
+ this.purchasePromiseResolve(eventData);
194
+ this.purchasePromiseResolve = null;
195
+ }
196
+ }
197
+ if (eventType === "game_state_updated") {
198
+ const eventData = data;
199
+ if (eventData) {
200
+ this._gameState = eventData.gameState;
201
+ } else {
202
+ this._gameState = null;
203
+ }
204
+ }
205
+ for (const callback of this.eventListeners.get(eventType) || []) {
206
+ callback(data);
207
+ }
208
+ }
209
+ handleMessage = (event) => {
210
+ if (event.data?.type !== "game_event")
148
211
  return;
149
- this.emit(gameEvent.type, gameEvent.data);
212
+ this.emit(event.data.event.type, event.data.event.data);
150
213
  };
151
- this.sendMessage = (type, data) => {
214
+ sendMessage = (type, data) => {
152
215
  if (!this.isClient || !this.target)
153
216
  return;
154
217
  const gameEvent = { type: "game_event", event: { type, data } };
155
218
  this.target.postMessage(gameEvent, "*");
156
219
  };
157
- this.handleGlobalError = (event) => {
220
+ handleGlobalError = (event) => {
158
221
  this.sendMessage("error", {
159
222
  message: event.message || "Unknown error",
160
223
  source: event.filename,
161
224
  lineno: event.lineno,
162
225
  colno: event.colno,
163
- error: event.error,
164
- stack: event.error instanceof Error ? event.error.stack : void 0
226
+ error: event.error
165
227
  });
166
228
  };
167
- this.handleUnhandledRejection = (event) => {
229
+ handleUnhandledRejection = (event) => {
168
230
  const error = event.reason instanceof Error ? event.reason : new Error(String(event.reason));
169
231
  this.sendMessage("error", {
170
232
  message: error.message,
171
- error,
172
- stack: error.stack
233
+ error
173
234
  });
174
235
  };
175
- this.isClient = isBrowserGameClient();
176
- this.target = this.isClient ? window.parent : null;
177
- if (this.isClient) {
178
- window.addEventListener("message", this.handleMessage);
179
- window.addEventListener("error", this.handleGlobalError);
180
- window.addEventListener("unhandledrejection", this.handleUnhandledRejection);
181
- this.sendMessage("ready", { instanceId: this.instanceId });
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;
202
- }
203
- }
204
- on(eventType, callback) {
205
- var _a;
206
- if (!this.eventListeners.has(eventType)) {
207
- this.eventListeners.set(eventType, /* @__PURE__ */ new Set());
208
- }
209
- (_a = this.eventListeners.get(eventType)) == null ? void 0 : _a.add(callback);
210
- return () => this.off(eventType, callback);
211
- }
212
- off(eventType, callback) {
213
- var _a;
214
- (_a = this.eventListeners.get(eventType)) == null ? void 0 : _a.delete(callback);
215
- }
216
- // explicitly named event listeners for better understanding and type safety;
217
- // each returns an unsubscribe function
218
- /**
219
- * Listen for the host starting play: a replay after game over, or — for level
220
- * games — a host-directed level via `data.levelIndex` (Studio continue/jump or
221
- * the production next-level button). `data` may be omitted for a plain restart.
222
- */
223
- onPlay(callback) {
224
- return this.on("play_again", (data) => callback(data));
225
- }
226
- /** @deprecated Use {@link onPlay}. Retained for backward compatibility. */
227
- onPlayAgain(callback) {
228
- return this.onPlay(callback);
229
- }
230
- onToggleMute(callback) {
231
- return this.on("toggle_mute", callback);
232
- }
233
- onGameStateUpdated(callback) {
234
- return this.on("game_state_updated", callback);
235
- }
236
- onGameInfo(callback) {
237
- return this.on("game_info", callback);
238
- }
239
- onPurchaseComplete(callback) {
240
- return this.on("purchase_complete", callback);
241
- }
242
- // end of explicitly named event listeners
243
- setTarget(target) {
244
- this.target = target;
245
- }
246
- get purchasedItems() {
247
- var _a;
248
- return ((_a = this._gameInfo) == null ? void 0 : _a.player.purchasedItems) || [];
249
- }
250
- get inventory() {
251
- const counts = /* @__PURE__ */ new Map();
252
- for (const item of this.purchasedItems) {
253
- counts.set(item, (counts.get(item) || 0) + 1);
254
- }
255
- return [...counts.entries()].map(([slug, quantity]) => ({ slug, quantity }));
256
- }
257
- get shopItems() {
258
- var _a;
259
- return ((_a = this._gameInfo) == null ? void 0 : _a.shopItems) || [];
260
- }
261
- get gameInfo() {
262
- return this._gameInfo;
263
- }
264
- get gameState() {
265
- return this._gameState;
266
- }
267
- get players() {
268
- var _a;
269
- return (_a = this._gameInfo) == null ? void 0 : _a.players;
270
- }
271
- get player() {
272
- var _a;
273
- return (_a = this._gameInfo) == null ? void 0 : _a.player;
274
- }
275
- get isReady() {
276
- return !!this._gameInfo;
277
- }
278
- /** True when the host configured this game with a fixed level count. */
279
- get isLevelBased() {
280
- var _a, _b;
281
- const levelCount = (_b = (_a = this._gameInfo) == null ? void 0 : _a.levelBased) == null ? void 0 : _b.levelCount;
282
- return levelCount != null && levelCount > 0;
283
- }
284
- /** Total levels for level-based games (from host metadata). */
285
- get levelCount() {
286
- var _a, _b;
287
- const levelCount = (_b = (_a = this._gameInfo) == null ? void 0 : _a.levelBased) == null ? void 0 : _b.levelCount;
288
- return levelCount != null && levelCount > 0 ? levelCount : void 0;
289
- }
290
- /** 1-based level index from score-derived progression, defaulting to 1. */
291
- get currentLevelIndex() {
292
- var _a, _b, _c;
293
- const value = (_c = (_b = (_a = this._gameInfo) == null ? void 0 : _a.levelBased) == null ? void 0 : _b.progress) == null ? void 0 : _c.currentLevelIndex;
294
- return typeof value === "number" && Number.isFinite(value) && value >= 1 ? value : 1;
295
- }
296
- /** Best stars earned per level from score-derived progression. Keys are 1-based level indices. */
297
- get levelStars() {
298
- return this._levelStars;
299
- }
300
- /** Highest unlocked level from score-derived progression, defaulting to 1. */
301
- get highestUnlockedLevel() {
302
- var _a, _b, _c;
303
- const value = (_c = (_b = (_a = this._gameInfo) == null ? void 0 : _a.levelBased) == null ? void 0 : _b.progress) == null ? void 0 : _c.highestUnlockedLevel;
304
- return typeof value === "number" && Number.isFinite(value) && value >= 1 ? value : 1;
305
- }
306
- /** Sum of best stars across all completed levels. */
307
- get totalStars() {
308
- return Object.values(this.levelStars).reduce((sum, stars) => sum + stars, 0);
309
- }
310
- emit(eventType, data) {
311
- var _a, _b, _c;
312
- if (eventType === "game_info") {
313
- const eventData = data;
314
- 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
- if (!this._gameState && eventData.initialGameState) {
326
- this._gameState = eventData.initialGameState.gameState;
327
- }
328
- if (this.readyPromiseResolve) {
329
- this.readyPromiseResolve(this._gameInfo);
330
- this.readyPromiseResolve = null;
331
- }
332
- }
333
- if (eventType === "purchase_complete") {
334
- const eventData = data;
335
- if (eventData.success && eventData.item && ((_c = this._gameInfo) == null ? void 0 : _c.player)) {
336
- this.applyPurchaseToCurrentPlayer(eventData.item);
337
- }
338
- const resolvePurchase = this.purchasePromiseResolvers.shift();
339
- if (resolvePurchase) {
340
- resolvePurchase(eventData);
341
- }
342
- }
343
- if (eventType === "game_state_updated") {
344
- const eventData = data;
345
- if (eventData) {
346
- this._gameState = eventData.gameState;
347
- } else {
348
- this._gameState = null;
349
- }
350
- }
351
- for (const callback of this.eventListeners.get(eventType) || []) {
352
- callback(data);
236
+ applyPurchaseToCurrentPlayer(item) {
237
+ if (!this._gameInfo)
238
+ return;
239
+ const currentPlayer = this._gameInfo.player;
240
+ currentPlayer.purchasedItems = [...currentPlayer.purchasedItems, item];
241
+ this._gameInfo.players = this._gameInfo.players.map((player) => {
242
+ if (player.id !== currentPlayer.id)
243
+ return player;
244
+ return {
245
+ ...player,
246
+ purchasedItems: currentPlayer.purchasedItems
247
+ };
248
+ });
353
249
  }
354
250
  }
355
- applyPurchaseToCurrentPlayer(item) {
356
- if (!this._gameInfo)
357
- return;
358
- const currentPlayer = this._gameInfo.player;
359
- currentPlayer.purchasedItems = [...currentPlayer.purchasedItems, item];
360
- for (const player of this._gameInfo.players) {
361
- if (player !== currentPlayer && player.id === currentPlayer.id) {
362
- player.purchasedItems = currentPlayer.purchasedItems;
363
- }
364
- }
251
+ var sdk = new RemixSDK;
252
+ if (typeof window !== "undefined") {
253
+ window.FarcadeSDK = sdk;
254
+ window.RemixSDK = sdk;
365
255
  }
366
- };
367
- var sdk = new RemixSDK();
368
- if (isBrowserGameClient()) {
369
- window.FarcadeSDK = sdk;
370
- window.RemixSDK = sdk;
371
- }
372
- // Annotate the CommonJS export names for ESM import in node:
373
- 0 && (module.exports = {
374
- RemixSDK,
375
- ZERO_SAFE_AREA_INSET,
376
- createGameEventMessage,
377
- parseGameEventMessage,
378
- sdk
379
- });
256
+ })();
257
+
258
+ //# debugId=5DCD609576A0948564756E2164756E21