@inappstory/game-center-api 1.3.26 → 1.3.28

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/lib/index.d.ts CHANGED
@@ -9,7 +9,7 @@ import { openUrl } from "./sdkApi/openUrl";
9
9
  import { shareText, shareUrl, shareFiles } from "./sdkApi/share";
10
10
  import { vibrate } from "./sdkApi/vibrate";
11
11
  import { ScreenOrientation, Placeholder, PlaceholderType, GameLaunchConfig } from "./gameLaunchConfig.h";
12
- import { fetchLocalFile } from "./sdkApi/fetchLocalFile";
12
+ import { fetchLocalFile, convertLocalFileUriToRemoteFileUri } from "./sdkApi/fetchLocalFile";
13
13
  import { openStory } from "./sdkApi/openStory";
14
14
  import { openGameInstance } from "./sdkApi/openGameInstance";
15
15
  import { eventGame } from "./sdkApi/events";
@@ -28,10 +28,11 @@ export type { ProjectFontFamily } from "./gameResources";
28
28
  export type { ResourceInterface } from "./ResourceManager";
29
29
  export type { OpenStoryOptions } from "./sdkApi/openStory.h";
30
30
  export type { OpenGameInstanceOptions } from "./sdkApi/openGameInstance.h";
31
- export { createSdkApi, closeGameReader, gameLoadedSdkCallback, gameLoadFailedSdkCallback, gameLaunchConfig, isIos, isWeb, isAndroid, isDev, getSdkVersion, getSemverSdkVersion, gameLocalData, sendIasApiRequest, openUrl, shareText, shareUrl, shareFiles, vibrate, getDynamicResourceAsset, getDynamicResourceFont, getProjectFontFamilyStylesheet, getIsDemoMode, getSessionId, getApiBaseUrl, ScreenOrientation, PlaceholderType, fetchLocalFile, openStory, ResourceManager, dynamicResourceAssets, dynamicResourceFonts, staticResourcesImagePlaceholders, StaticResourceList, eventGame, reloadGameReader, openFilePicker, FilePickerResultType, isFilePickerResultFileList, isFilePickerResultLocalFileList, isLocalFile, hasFilePickerApi, gameShouldForegroundCallback, gameOnForeground, getApplicationVersion, getApplicationBuildVersion, openGameInstance, logError, logWarning, UserAccelerationSensor, base64url_decode, };
31
+ export type { FetchLocalFileOptions } from "./sdkApi/fetchLocalFile";
32
+ export { createSdkApi, closeGameReader, gameLoadedSdkCallback, gameLoadFailedSdkCallback, gameLaunchConfig, isIos, isWeb, isAndroid, isDev, getSdkVersion, getSemverSdkVersion, gameLocalData, sendIasApiRequest, openUrl, shareText, shareUrl, shareFiles, vibrate, getDynamicResourceAsset, getDynamicResourceFont, getProjectFontFamilyStylesheet, getIsDemoMode, getSessionId, getApiBaseUrl, ScreenOrientation, PlaceholderType, fetchLocalFile, convertLocalFileUriToRemoteFileUri, openStory, ResourceManager, dynamicResourceAssets, dynamicResourceFonts, staticResourcesImagePlaceholders, StaticResourceList, eventGame, reloadGameReader, openFilePicker, FilePickerResultType, isFilePickerResultFileList, isFilePickerResultLocalFileList, isLocalFile, hasFilePickerApi, gameShouldForegroundCallback, gameOnForeground, getApplicationVersion, getApplicationBuildVersion, openGameInstance, logError, logWarning, UserAccelerationSensor, base64url_decode, };
32
33
  declare const GameCenterApi: {
33
34
  createSdkApi: ({ mounted, beforeUnmount: beforeUnmountCb, onSdkCloseGameReaderIntent, onPause, onResume, onBackGesture, onAudioFocusChange, filterPlaceholders, gameShouldForeground, }: Partial<{
34
- mounted: () => void;
35
+ mounted: () => Promise<void>;
35
36
  beforeUnmount: () => void;
36
37
  onSdkCloseGameReaderIntent: () => void;
37
38
  onPause: () => void;
@@ -71,6 +72,7 @@ declare const GameCenterApi: {
71
72
  ScreenOrientation: typeof ScreenOrientation;
72
73
  PlaceholderType: typeof PlaceholderType;
73
74
  fetchLocalFile: typeof fetchLocalFile;
75
+ convertLocalFileUriToRemoteFileUri: (uri: string) => string;
74
76
  openStory: (openStory: import("./sdkApi/openStory.h").OpenStoryOptions) => void;
75
77
  ResourceManager: typeof ResourceManager;
76
78
  dynamicResourceAssets: import("./gameResources").DynamicResourceAssets;
package/lib/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.base64url_decode = exports.UserAccelerationSensor = exports.logWarning = exports.logError = exports.openGameInstance = exports.getApplicationBuildVersion = exports.getApplicationVersion = exports.gameOnForeground = exports.gameShouldForegroundCallback = exports.hasFilePickerApi = exports.isLocalFile = exports.isFilePickerResultLocalFileList = exports.isFilePickerResultFileList = exports.FilePickerResultType = exports.openFilePicker = exports.reloadGameReader = exports.eventGame = exports.StaticResourceList = exports.staticResourcesImagePlaceholders = exports.dynamicResourceFonts = exports.dynamicResourceAssets = exports.ResourceManager = exports.openStory = exports.fetchLocalFile = exports.PlaceholderType = exports.ScreenOrientation = exports.getApiBaseUrl = exports.getSessionId = exports.getIsDemoMode = exports.getProjectFontFamilyStylesheet = exports.getDynamicResourceFont = exports.getDynamicResourceAsset = exports.vibrate = exports.shareFiles = exports.shareUrl = exports.shareText = exports.openUrl = exports.sendIasApiRequest = exports.gameLocalData = exports.getSemverSdkVersion = exports.getSdkVersion = exports.isDev = exports.isAndroid = exports.isWeb = exports.isIos = exports.gameLaunchConfig = exports.gameLoadFailedSdkCallback = exports.gameLoadedSdkCallback = exports.closeGameReader = exports.createSdkApi = void 0;
4
- exports.TraceablePromise = exports.default = void 0;
3
+ exports.UserAccelerationSensor = exports.logWarning = exports.logError = exports.openGameInstance = exports.getApplicationBuildVersion = exports.getApplicationVersion = exports.gameOnForeground = exports.gameShouldForegroundCallback = exports.hasFilePickerApi = exports.isLocalFile = exports.isFilePickerResultLocalFileList = exports.isFilePickerResultFileList = exports.FilePickerResultType = exports.openFilePicker = exports.reloadGameReader = exports.eventGame = exports.StaticResourceList = exports.staticResourcesImagePlaceholders = exports.dynamicResourceFonts = exports.dynamicResourceAssets = exports.ResourceManager = exports.openStory = exports.convertLocalFileUriToRemoteFileUri = exports.fetchLocalFile = exports.PlaceholderType = exports.ScreenOrientation = exports.getApiBaseUrl = exports.getSessionId = exports.getIsDemoMode = exports.getProjectFontFamilyStylesheet = exports.getDynamicResourceFont = exports.getDynamicResourceAsset = exports.vibrate = exports.shareFiles = exports.shareUrl = exports.shareText = exports.openUrl = exports.sendIasApiRequest = exports.gameLocalData = exports.getSemverSdkVersion = exports.getSdkVersion = exports.isDev = exports.isAndroid = exports.isWeb = exports.isIos = exports.gameLaunchConfig = exports.gameLoadFailedSdkCallback = exports.gameLoadedSdkCallback = exports.closeGameReader = exports.createSdkApi = void 0;
4
+ exports.TraceablePromise = exports.default = exports.base64url_decode = void 0;
5
5
  const env_1 = require("./env");
6
6
  Object.defineProperty(exports, "getApplicationBuildVersion", { enumerable: true, get: function () { return env_1.getApplicationBuildVersion; } });
7
7
  Object.defineProperty(exports, "getApplicationVersion", { enumerable: true, get: function () { return env_1.getApplicationVersion; } });
@@ -50,6 +50,7 @@ Object.defineProperty(exports, "ScreenOrientation", { enumerable: true, get: fun
50
50
  Object.defineProperty(exports, "PlaceholderType", { enumerable: true, get: function () { return gameLaunchConfig_h_1.PlaceholderType; } });
51
51
  const fetchLocalFile_1 = require("./sdkApi/fetchLocalFile");
52
52
  Object.defineProperty(exports, "fetchLocalFile", { enumerable: true, get: function () { return fetchLocalFile_1.fetchLocalFile; } });
53
+ Object.defineProperty(exports, "convertLocalFileUriToRemoteFileUri", { enumerable: true, get: function () { return fetchLocalFile_1.convertLocalFileUriToRemoteFileUri; } });
53
54
  const openStory_1 = require("./sdkApi/openStory");
54
55
  Object.defineProperty(exports, "openStory", { enumerable: true, get: function () { return openStory_1.openStory; } });
55
56
  const openGameInstance_1 = require("./sdkApi/openGameInstance");
@@ -101,6 +102,7 @@ const GameCenterApi = {
101
102
  ScreenOrientation: gameLaunchConfig_h_1.ScreenOrientation,
102
103
  PlaceholderType: gameLaunchConfig_h_1.PlaceholderType,
103
104
  fetchLocalFile: fetchLocalFile_1.fetchLocalFile,
105
+ convertLocalFileUriToRemoteFileUri: fetchLocalFile_1.convertLocalFileUriToRemoteFileUri,
104
106
  openStory: openStory_1.openStory,
105
107
  ResourceManager: ResourceManager_1.ResourceManager,
106
108
  dynamicResourceAssets: gameResources_1.dynamicResourceAssets,
@@ -1 +1,12 @@
1
- export declare function fetchLocalFile(url: string, remoteUrl?: string): Promise<Response | undefined>;
1
+ export type FetchLocalFileOptions = {
2
+ remoteUrl?: string;
3
+ fetchOptions?: RequestInit;
4
+ iOSUseXhr?: boolean;
5
+ AndroidUseXhr?: boolean;
6
+ xhrResponseHeaders?: Array<[key: string, value: string]>;
7
+ };
8
+ export declare function fetchLocalFile(url: string, options?: FetchLocalFileOptions | undefined): Promise<Response | undefined>;
9
+ /**
10
+ * Provide remote network URI - for fetchLocalFile fallback src (applied only for Native SDK)
11
+ */
12
+ export declare const convertLocalFileUriToRemoteFileUri: (uri: string) => string;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.fetchLocalFile = void 0;
3
+ exports.convertLocalFileUriToRemoteFileUri = exports.fetchLocalFile = void 0;
4
4
  const env_1 = require("../env");
5
5
  const eventLogger_1 = require("../eventLogger");
6
+ const gameLaunchConfig_1 = require("../gameLaunchConfig");
6
7
  const semver = require("semver");
7
8
  let instance;
8
9
  class URLResolver {
@@ -21,14 +22,14 @@ class URLResolver {
21
22
  return this._link.href;
22
23
  }
23
24
  }
24
- function fetchLocalAndroid(url) {
25
+ function fetchLocalAndroid(url, init) {
25
26
  if (url.substring(0, 1) === "/" || url.substring(0, 2) === "./") {
26
27
  url = URLResolver.getInstance().resolve(url);
27
28
  }
28
29
  // if sdk 1.16.2+
29
- return fetch(url.replace("file:///", "http://file-assets/"));
30
+ return fetch(url.replace("file:///", "http://file-assets/"), init);
30
31
  }
31
- function fetchLocalFile(url, remoteUrl) {
32
+ function fetchLocalFile(url, options) {
32
33
  if (env_1.isAndroid) {
33
34
  const semverVersion = (0, env_1.getSemverSdkVersion)();
34
35
  let sdkSupportFileAssetsProtocol = true;
@@ -44,62 +45,122 @@ function fetchLocalFile(url, remoteUrl) {
44
45
  sdkSupportFileAssetsProtocol = false;
45
46
  }
46
47
  }
48
+ const fetchViaXhr = () => new Promise(function (resolve, reject) {
49
+ const xhr = new XMLHttpRequest();
50
+ xhr.onload = function () {
51
+ // status 0 in android 9+
52
+ try {
53
+ resolve(new Response(xhr.response, {
54
+ status: xhr.status >= 200 && xhr.status <= 599 ? xhr.status : 200,
55
+ headers: options?.xhrResponseHeaders ? new Headers(options?.xhrResponseHeaders) : undefined,
56
+ }));
57
+ }
58
+ catch (e) {
59
+ (0, eventLogger_1.logError)(e);
60
+ reject(e);
61
+ }
62
+ };
63
+ xhr.onerror = function () {
64
+ reject(new TypeError("Local request failed"));
65
+ };
66
+ xhr.open("GET", url);
67
+ xhr.responseType = "arraybuffer";
68
+ xhr.send(null);
69
+ });
47
70
  if (sdkSupportFileAssetsProtocol) {
48
- return fetchLocalAndroid(url);
71
+ if (options?.AndroidUseXhr) {
72
+ return fetchViaXhr();
73
+ }
74
+ return fetchLocalAndroid(url, options?.fetchOptions);
49
75
  }
50
76
  else {
51
77
  if (!sdkCanFetchLocalFile) {
52
- remoteUrl += "&stamp=" + new Date().getTime();
53
- if (!remoteUrl) {
78
+ if (!options?.remoteUrl) {
54
79
  return Promise.resolve(undefined);
55
80
  }
56
- return fetch(remoteUrl);
81
+ return fetch(options.remoteUrl + "&stamp=" + new Date().getTime(), options?.fetchOptions);
57
82
  }
58
83
  else {
59
- return new Promise(function (resolve, reject) {
60
- const xhr = new XMLHttpRequest();
61
- xhr.onload = function () {
62
- // status 0 in android 9+
63
- try {
64
- resolve(new Response(xhr.response, { status: xhr.status >= 200 && xhr.status <= 599 ? xhr.status : 200 }));
65
- }
66
- catch (e) {
67
- (0, eventLogger_1.logError)(e);
68
- reject(e);
69
- }
70
- };
71
- xhr.onerror = function () {
72
- reject(new TypeError("Local request failed"));
73
- };
74
- xhr.open("GET", url);
75
- xhr.responseType = "arraybuffer";
76
- xhr.send(null);
77
- });
84
+ return fetchViaXhr();
78
85
  }
79
86
  }
80
87
  }
81
88
  else if (env_1.isIos) {
82
- // https://stackoverflow.com/questions/40182785/why-fetch-return-a-response-with-status-0
83
- // Effectively, the response you get from making such a request (with no-cors specified as a mode) will contain no information about whether the request succeeded or failed, making the status code 0.
84
- // Welcome to the insane and wonderful world of CORS. A necessary(?) evil; CORS is a huge pain the ass for web developers.
85
- // fetch local file on iOS return status 0, response.ok = false
86
- // fallback via wrap fetch result into new Response with status 200
87
- // assume that failed load - trigger catch by origin fetch
88
- return new Promise(function (resolve, reject) {
89
- fetch(url)
90
- .then(response => {
91
- if (response.status === 0) {
92
- resolve(new Response(response.body, { status: 200 }));
93
- }
94
- else {
95
- resolve(response);
96
- }
97
- })
98
- .catch(reject);
99
- });
89
+ if (options?.iOSUseXhr) {
90
+ return new Promise(function (resolve, reject) {
91
+ const xhr = new XMLHttpRequest();
92
+ xhr.onload = function () {
93
+ try {
94
+ resolve(new Response(xhr.response, {
95
+ status: 200,
96
+ headers: options?.xhrResponseHeaders ? new Headers(options?.xhrResponseHeaders) : undefined,
97
+ }));
98
+ }
99
+ catch (e) {
100
+ (0, eventLogger_1.logError)(e);
101
+ reject(e);
102
+ }
103
+ };
104
+ xhr.onerror = function () {
105
+ reject(new TypeError("Local request failed"));
106
+ };
107
+ xhr.open("GET", url);
108
+ xhr.responseType = "arraybuffer";
109
+ xhr.send(null);
110
+ });
111
+ }
112
+ else {
113
+ // https://stackoverflow.com/questions/40182785/why-fetch-return-a-response-with-status-0
114
+ // Effectively, the response you get from making such a request (with no-cors specified as a mode) will contain no information about whether the request succeeded or failed, making the status code 0.
115
+ // Welcome to the insane and wonderful world of CORS. A necessary(?) evil; CORS is a huge pain the ass for web developers.
116
+ // fetch local file on iOS return status 0, response.ok = false
117
+ // fallback via wrap fetch result into new Response with status 200
118
+ // assume that failed load - trigger catch by origin fetch
119
+ return new Promise(function (resolve, reject) {
120
+ fetch(url)
121
+ .then(response => {
122
+ if (response.status === 0) {
123
+ resolve(new Response(response.body, { status: 200 }));
124
+ }
125
+ else {
126
+ resolve(response);
127
+ }
128
+ })
129
+ .catch(reject);
130
+ });
131
+ }
100
132
  }
101
133
  else {
102
134
  return fetch(url);
103
135
  }
104
136
  }
105
137
  exports.fetchLocalFile = fetchLocalFile;
138
+ /**
139
+ * Provide remote network URI - for fetchLocalFile fallback src (applied only for Native SDK)
140
+ */
141
+ const convertLocalFileUriToRemoteFileUri = (uri) => {
142
+ let baseUri = String(gameLaunchConfig_1.gameLaunchConfig.gameDomain).trimEnd();
143
+ if (baseUri.charAt(baseUri.length - 1) !== "/") {
144
+ baseUri += "/";
145
+ }
146
+ let pathname = uri;
147
+ if (uri.substring(0, 1) === "/" || uri.substring(0, 2) === "./") {
148
+ pathname = uri;
149
+ }
150
+ else {
151
+ try {
152
+ pathname = new URL(uri).pathname;
153
+ }
154
+ catch (e) {
155
+ console.error(e);
156
+ }
157
+ }
158
+ if (pathname.substring(0, 1) === "/") {
159
+ pathname = pathname.substring(1);
160
+ }
161
+ else if (pathname.substring(0, 2) === "./") {
162
+ pathname = pathname.substring(2);
163
+ }
164
+ return baseUri + pathname;
165
+ };
166
+ exports.convertLocalFileUriToRemoteFileUri = convertLocalFileUriToRemoteFileUri;
@@ -1,6 +1,6 @@
1
1
  import { Placeholder } from "../gameLaunchConfig.h";
2
2
  export type SdkApiCallbacks = Partial<{
3
- mounted: () => void;
3
+ mounted: () => Promise<void>;
4
4
  beforeUnmount: () => void;
5
5
  onSdkCloseGameReaderIntent: () => void;
6
6
  onPause: () => void;
@@ -30,7 +30,7 @@ type GameReaderInit = {
30
30
  _e: Array<() => void>;
31
31
  ready: (cb: () => void) => void;
32
32
  };
33
- export declare const createInitGame: (initLocalData: () => Promise<void>, mounted?: () => void) => void;
33
+ export declare const createInitGame: (initLocalData: () => Promise<void>, mounted?: () => Promise<void>) => void;
34
34
  /**
35
35
  * API method for remove loader screen from Reader
36
36
  */
@@ -91,7 +91,7 @@ const gameReader = (function () {
91
91
  return self;
92
92
  })();
93
93
  window.gameReader = gameReader;
94
- const createInitGame = (initLocalData, mounted = () => { }) => {
94
+ const createInitGame = (initLocalData, mounted = () => Promise.resolve()) => {
95
95
  window.initGame = async function (config) {
96
96
  try {
97
97
  // prevent call window.gameLoadFailed from fallback 30s timer (if js bundle parsed and ready)
@@ -124,7 +124,12 @@ const createInitGame = (initLocalData, mounted = () => { }) => {
124
124
  (0, eventLogger_1.logError)(e);
125
125
  throw e;
126
126
  }
127
- mounted();
127
+ try {
128
+ await mounted();
129
+ }
130
+ catch (e) {
131
+ (0, exports.gameLoadFailedSdkCallback)(e.message, false);
132
+ }
128
133
  window.gameLoadingInfo.state = "after call initGame";
129
134
  window.gameLoadingInfo.description = JSON.stringify(config);
130
135
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inappstory/game-center-api",
3
- "version": "1.3.26",
3
+ "version": "1.3.28",
4
4
  "description": "",
5
5
  "dependencies": {
6
6
  "@sentry/browser": "^9.5.0",