@playcademy/sdk 0.5.0 → 0.5.1-beta.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/internal.js CHANGED
@@ -25,6 +25,7 @@ var MessageEvents;
25
25
  MessageEvents2["TELEMETRY"] = "PLAYCADEMY_TELEMETRY";
26
26
  MessageEvents2["KEY_EVENT"] = "PLAYCADEMY_KEY_EVENT";
27
27
  MessageEvents2["DISPLAY_ALERT"] = "PLAYCADEMY_DISPLAY_ALERT";
28
+ MessageEvents2["DEMO_END"] = "PLAYCADEMY_DEMO_END";
28
29
  MessageEvents2["AUTH_STATE_CHANGE"] = "PLAYCADEMY_AUTH_STATE_CHANGE";
29
30
  MessageEvents2["AUTH_CALLBACK"] = "PLAYCADEMY_AUTH_CALLBACK";
30
31
  })(MessageEvents ||= {});
@@ -84,7 +85,8 @@ class PlaycademyMessaging {
84
85
  "PLAYCADEMY_EXIT" /* EXIT */,
85
86
  "PLAYCADEMY_TELEMETRY" /* TELEMETRY */,
86
87
  "PLAYCADEMY_KEY_EVENT" /* KEY_EVENT */,
87
- "PLAYCADEMY_DISPLAY_ALERT" /* DISPLAY_ALERT */
88
+ "PLAYCADEMY_DISPLAY_ALERT" /* DISPLAY_ALERT */,
89
+ "PLAYCADEMY_DEMO_END" /* DEMO_END */
88
90
  ];
89
91
  const shouldUsePostMessage = isIframe && iframeToParentEvents.includes(eventType);
90
92
  return {
@@ -185,7 +187,8 @@ function createStandaloneConfig() {
185
187
  gameUrl: globalThis.location.origin,
186
188
  token: "mock-game-token-for-local-dev",
187
189
  gameId: "mock-game-id-from-template",
188
- realtimeUrl: undefined
190
+ realtimeUrl: undefined,
191
+ mode: "standalone"
189
192
  };
190
193
  globalThis.PLAYCADEMY = mockConfig;
191
194
  return mockConfig;
@@ -203,6 +206,7 @@ async function init(options) {
203
206
  gameUrl: config.gameUrl,
204
207
  token: config.token,
205
208
  gameId: config.gameId,
209
+ mode: config.mode,
206
210
  autoStartSession: globalThis.self !== window.top,
207
211
  onDisconnect: options?.onDisconnect,
208
212
  enableConnectionMonitoring: options?.enableConnectionMonitoring
@@ -850,7 +854,12 @@ async function login2(client, options) {
850
854
  // src/namespaces/game/identity.ts
851
855
  function createIdentityNamespace(client) {
852
856
  return {
853
- connect: (options) => login2(client, options),
857
+ connect: (options) => {
858
+ if (client.mode === "demo") {
859
+ throw new PlaycademyError("identity.connect() is not available in demo mode. Use platform or standalone mode for OAuth flows.");
860
+ }
861
+ return login2(client, options);
862
+ },
854
863
  _getContext: () => ({
855
864
  isInIframe: client["authContext"]?.isInIframe ?? false
856
865
  })
@@ -1050,6 +1059,42 @@ function createBackendNamespace(client) {
1050
1059
  }
1051
1060
  };
1052
1061
  }
1062
+ // src/namespaces/game/guard.ts
1063
+ function assertPlatformMode(client, operation) {
1064
+ if (client.mode !== "platform") {
1065
+ throw new PlaycademyError(`${operation} requires platform mode (current: ${client.mode}). Check client.mode before calling.`);
1066
+ }
1067
+ }
1068
+ function assertDemoMode(client, operation) {
1069
+ if (client.mode !== "demo") {
1070
+ throw new PlaycademyError(`${operation} requires demo mode (current: ${client.mode}). Check client.mode before calling.`);
1071
+ }
1072
+ }
1073
+
1074
+ // src/namespaces/game/demo.ts
1075
+ function createDemoNamespace(client) {
1076
+ return {
1077
+ profile: {
1078
+ get: async () => {
1079
+ assertDemoMode(client, "demo.profile.get()");
1080
+ return client["request"]("/users/demo-profile", "GET");
1081
+ },
1082
+ update: async (updates) => {
1083
+ assertDemoMode(client, "demo.profile.update()");
1084
+ return client["request"]("/users/demo-profile", "PATCH", {
1085
+ body: updates
1086
+ });
1087
+ }
1088
+ },
1089
+ end: (score, options) => {
1090
+ assertDemoMode(client, "demo.end()");
1091
+ messaging.send("PLAYCADEMY_DEMO_END" /* DEMO_END */, {
1092
+ score,
1093
+ ...options
1094
+ });
1095
+ }
1096
+ };
1097
+ }
1053
1098
  // src/core/cache/permanent-cache.ts
1054
1099
  function createPermanentCache(keyPrefix) {
1055
1100
  const cache = new Map;
@@ -1112,10 +1157,17 @@ function createUsersNamespace(client) {
1112
1157
  });
1113
1158
  }
1114
1159
  return {
1115
- me: async () => client["request"]("/users/me", "GET"),
1160
+ me: async () => {
1161
+ assertPlatformMode(client, "users.me()");
1162
+ return client["request"]("/users/me", "GET");
1163
+ },
1116
1164
  inventory: {
1117
- get: async () => client["request"](`/inventory`, "GET"),
1165
+ get: async () => {
1166
+ assertPlatformMode(client, "users.inventory.get()");
1167
+ return client["request"](`/inventory`, "GET");
1168
+ },
1118
1169
  add: async (identifier, qty) => {
1170
+ assertPlatformMode(client, "users.inventory.add()");
1119
1171
  const itemId = await resolveItemId(identifier);
1120
1172
  const res = await client["request"](`/inventory/add`, "POST", { body: { itemId, qty } });
1121
1173
  client["emit"]("inventoryChange", {
@@ -1126,6 +1178,7 @@ function createUsersNamespace(client) {
1126
1178
  return res;
1127
1179
  },
1128
1180
  remove: async (identifier, qty) => {
1181
+ assertPlatformMode(client, "users.inventory.remove()");
1129
1182
  const itemId = await resolveItemId(identifier);
1130
1183
  const res = await client["request"](`/inventory/remove`, "POST", { body: { itemId, qty } });
1131
1184
  client["emit"]("inventoryChange", {
@@ -1136,12 +1189,14 @@ function createUsersNamespace(client) {
1136
1189
  return res;
1137
1190
  },
1138
1191
  quantity: async (identifier) => {
1192
+ assertPlatformMode(client, "users.inventory.quantity()");
1139
1193
  const itemId = await resolveItemId(identifier);
1140
1194
  const inventory = await client["request"](`/inventory`, "GET");
1141
1195
  const item = inventory.find((inv) => inv.item?.id === itemId);
1142
1196
  return item?.quantity ?? 0;
1143
1197
  },
1144
1198
  has: async (identifier, minQuantity = 1) => {
1199
+ assertPlatformMode(client, "users.inventory.has()");
1145
1200
  const itemId = await resolveItemId(identifier);
1146
1201
  const inventory = await client["request"](`/inventory`, "GET");
1147
1202
  const item = inventory.find((inv) => inv.item?.id === itemId);
@@ -1315,11 +1370,13 @@ function createCreditsNamespace(client) {
1315
1370
  }
1316
1371
  return {
1317
1372
  balance: async () => {
1373
+ assertPlatformMode(client, "credits.balance()");
1318
1374
  const inventory = await client["request"]("/inventory", "GET");
1319
1375
  const primaryCurrencyInventoryItem = inventory.find((item) => item.item?.slug === CURRENCIES.PRIMARY);
1320
1376
  return primaryCurrencyInventoryItem?.quantity ?? 0;
1321
1377
  },
1322
1378
  add: async (amount) => {
1379
+ assertPlatformMode(client, "credits.add()");
1323
1380
  if (amount <= 0) {
1324
1381
  throw new Error("Amount must be positive");
1325
1382
  }
@@ -1338,6 +1395,7 @@ function createCreditsNamespace(client) {
1338
1395
  return result.newTotal;
1339
1396
  },
1340
1397
  spend: async (amount) => {
1398
+ assertPlatformMode(client, "credits.spend()");
1341
1399
  if (amount <= 0) {
1342
1400
  throw new Error("Amount must be positive");
1343
1401
  }
@@ -1360,12 +1418,15 @@ function createCreditsNamespace(client) {
1360
1418
  // src/namespaces/game/scores.ts
1361
1419
  function createScoresNamespace(client) {
1362
1420
  return {
1363
- submit: async (gameId, score, metadata) => client["request"](`/games/${gameId}/scores`, "POST", {
1364
- body: {
1365
- score,
1366
- metadata
1367
- }
1368
- })
1421
+ submit: async (score, metadata) => {
1422
+ const gameId = client["_ensureGameId"]();
1423
+ return client["request"](`/games/${gameId}/scores`, "POST", {
1424
+ body: {
1425
+ score,
1426
+ metadata
1427
+ }
1428
+ });
1429
+ }
1369
1430
  };
1370
1431
  }
1371
1432
  // src/namespaces/game/realtime.ts
@@ -1373,6 +1434,7 @@ function createRealtimeNamespace(client) {
1373
1434
  return {
1374
1435
  token: {
1375
1436
  get: async () => {
1437
+ assertPlatformMode(client, "realtime.token.get()");
1376
1438
  const endpoint = client["gameId"] ? `/games/${client["gameId"]}/realtime/token` : "/realtime/token";
1377
1439
  return client["request"](endpoint, "POST");
1378
1440
  }
@@ -1826,6 +1888,7 @@ function createTimebackNamespace(client) {
1826
1888
  }
1827
1889
  return {
1828
1890
  get user() {
1891
+ assertPlatformMode(client, "timeback.user");
1829
1892
  return {
1830
1893
  get id() {
1831
1894
  return getTimeback()?.id;
@@ -1898,15 +1961,21 @@ function createTimebackNamespace(client) {
1898
1961
  };
1899
1962
  },
1900
1963
  startActivity: (metadata, options) => {
1964
+ assertPlatformMode(client, "timeback.startActivity()");
1901
1965
  activityTracker.startActivity(metadata, options);
1902
1966
  },
1903
1967
  pauseActivity: () => {
1968
+ assertPlatformMode(client, "timeback.pauseActivity()");
1904
1969
  activityTracker.pauseActivity();
1905
1970
  },
1906
1971
  resumeActivity: () => {
1972
+ assertPlatformMode(client, "timeback.resumeActivity()");
1907
1973
  activityTracker.resumeActivity();
1908
1974
  },
1909
- endActivity: async (data) => activityTracker.endActivity(data)
1975
+ endActivity: async (data) => {
1976
+ assertPlatformMode(client, "timeback.endActivity()");
1977
+ return activityTracker.endActivity(data);
1978
+ }
1910
1979
  };
1911
1980
  }
1912
1981
  // src/namespaces/platform/auth.ts
@@ -2464,22 +2533,37 @@ function createAchievementsNamespace(client) {
2464
2533
  };
2465
2534
  }
2466
2535
  // src/namespaces/platform/leaderboard.ts
2536
+ async function fetchInternalLeaderboardEntries(client, options) {
2537
+ const params = new URLSearchParams({
2538
+ timeframe: options?.timeframe || "all_time",
2539
+ limit: String(options?.limit || 10),
2540
+ offset: String(options?.offset || 0)
2541
+ });
2542
+ if (options?.gameId) {
2543
+ params.append("gameId", options.gameId);
2544
+ }
2545
+ return client["request"](`/leaderboard?${params}`, "GET");
2546
+ }
2547
+ async function fetchPublicLeaderboardEntries(client, options) {
2548
+ const params = new URLSearchParams({
2549
+ timeframe: options?.timeframe || "all_time",
2550
+ limit: String(options?.limit || 10),
2551
+ offset: String(options?.offset || 0)
2552
+ });
2553
+ params.append("gameId", options?.gameId || client["_ensureGameId"]());
2554
+ return client["request"](`/leaderboard?${params}`, "GET");
2555
+ }
2467
2556
  function createLeaderboardNamespace(client) {
2468
2557
  return {
2469
- fetch: async (options) => {
2470
- const params = new URLSearchParams({
2471
- timeframe: options?.timeframe || "all_time",
2472
- limit: String(options?.limit || 10),
2473
- offset: String(options?.offset || 0)
2474
- });
2475
- if (options?.gameId) {
2476
- params.append("gameId", options.gameId);
2477
- }
2478
- return client["request"](`/leaderboard?${params}`, "GET");
2479
- },
2558
+ fetch: async (options) => fetchInternalLeaderboardEntries(client, options),
2480
2559
  getUserRank: async (gameId, userId) => client["request"](`/games/${gameId}/users/${userId}/rank`, "GET")
2481
2560
  };
2482
2561
  }
2562
+ function createLeaderboardFetchNamespace(client) {
2563
+ return {
2564
+ fetch: async (options) => fetchPublicLeaderboardEntries(client, options)
2565
+ };
2566
+ }
2483
2567
  // src/core/cache/cooldown-cache.ts
2484
2568
  function createCooldownCache(defaultCooldownMs) {
2485
2569
  const lastFetchTime = new Map;
@@ -2691,9 +2775,13 @@ function createTelemetryNamespace(client) {
2691
2775
  }
2692
2776
  // src/namespaces/platform/scores.ts
2693
2777
  function createScoresNamespace2(client) {
2694
- const publicScores = createScoresNamespace(client);
2695
2778
  return {
2696
- ...publicScores,
2779
+ submit: async (gameId, score, metadata) => client["request"](`/games/${gameId}/scores`, "POST", {
2780
+ body: {
2781
+ score,
2782
+ metadata
2783
+ }
2784
+ }),
2697
2785
  getByUser: async (gameId, userId, options) => {
2698
2786
  const params = new URLSearchParams;
2699
2787
  if (options?.limit) {
@@ -3317,6 +3405,7 @@ async function request({
3317
3405
  class PlaycademyBaseClient {
3318
3406
  baseUrl;
3319
3407
  gameUrl;
3408
+ mode;
3320
3409
  authStrategy;
3321
3410
  gameId;
3322
3411
  config;
@@ -3333,6 +3422,7 @@ class PlaycademyBaseClient {
3333
3422
  constructor(config) {
3334
3423
  this.baseUrl = config?.baseUrl?.endsWith("/api") ? config.baseUrl : `${config?.baseUrl}/api`;
3335
3424
  this.gameUrl = config?.gameUrl;
3425
+ this.mode = config?.mode ?? "platform";
3336
3426
  this.gameId = config?.gameId;
3337
3427
  this.launchId = config?.launchId ?? undefined;
3338
3428
  this.config = config || {};