@maoyugames/phaser-framework 1.0.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.
@@ -0,0 +1,34 @@
1
+ import { p as PlatformName, h as IPlatformDevice, i as IPlatformLifecycle } from '../types-DtcRFbM0.js';
2
+ import { B as BasePlatform } from '../BasePlatform-BCOkvvDW.js';
3
+
4
+ /**
5
+ * Capacitor(原生 WebView 容器)平台适配器。
6
+ *
7
+ * - hasDOM=true(运行在原生 WebView), isMiniGame=false
8
+ * - net:fetch + 标准 WebSocket(继承 BasePlatform)
9
+ * - storage:localStorage(继承 BasePlatform;Capacitor WebView 的 localStorage 持久可靠)。
10
+ * 注:@capacitor/preferences 是异步 KV,与同步 IPlatformStorage 不匹配,
11
+ * 故不硬依赖;若业务需要更强持久化,可在 game 侧封装 Preferences 并自行迁移。
12
+ * - lifecycle:优先用 @capacitor/app 的 appStateChange(通过全局 Capacitor.Plugins.App 探测),
13
+ * 缺失则退回 DOM visibilitychange(BasePlatform 提供)。
14
+ * - device:vibrate 优先用 Haptics 插件(全局探测),缺失退回 navigator.vibrate;
15
+ * clipboard / share 优先用对应插件,缺失退回浏览器 API。
16
+ * - ads / payment:Capacitor 无内置实现,保持 undefined。
17
+ *
18
+ * 如何接广告 / 内购(由具体游戏在 src/game 扩展):
19
+ * 1. 安装对应 Capacitor 插件,如 AdMob(@capacitor-community/admob)、
20
+ * IAP(@capacitor-community/in-app-purchases / RevenueCat 等)。
21
+ * 2. 在 game 侧实现 IPlatformAds / IPlatformPayment 适配器(静态 import 插件),
22
+ * 并在自定义 startGame 流程里注入到平台实例,或扩展本类的子类覆盖 ads/payment。
23
+ * 3. 不要在本框架核心层硬依赖这些插件,以免污染其它平台构建。
24
+ */
25
+
26
+ declare class CapacitorPlatform extends BasePlatform {
27
+ readonly platformName: PlatformName;
28
+ readonly isMiniGame = false;
29
+ readonly device: IPlatformDevice;
30
+ readonly lifecycle: IPlatformLifecycle;
31
+ init(): Promise<void>;
32
+ }
33
+
34
+ export { CapacitorPlatform };
@@ -0,0 +1,145 @@
1
+ import { BasePlatform, DomLifecycle } from '../chunk-H5CUVYCN.js';
2
+ import { PlatformUnsupportedError } from '../chunk-II3JM4R3.js';
3
+ import { __publicField } from '../chunk-PKBMQBKP.js';
4
+
5
+ // src/platform/impl/capacitor/CapacitorPlatform.ts
6
+ function getCapacitor() {
7
+ return typeof window !== "undefined" ? window.Capacitor : void 0;
8
+ }
9
+ function isNative() {
10
+ const cap = getCapacitor();
11
+ try {
12
+ return !!cap && cap.isNativePlatform();
13
+ } catch {
14
+ return false;
15
+ }
16
+ }
17
+ var CapacitorDevice = class {
18
+ vibrateShort() {
19
+ const haptics = getCapacitor()?.Plugins?.Haptics;
20
+ if (haptics?.impact) {
21
+ void haptics.impact({ style: "LIGHT" }).catch(() => {
22
+ });
23
+ return;
24
+ }
25
+ try {
26
+ navigator.vibrate?.(15);
27
+ } catch {
28
+ }
29
+ }
30
+ vibrateLong() {
31
+ const haptics = getCapacitor()?.Plugins?.Haptics;
32
+ if (haptics?.vibrate) {
33
+ void haptics.vibrate({ duration: 400 }).catch(() => {
34
+ });
35
+ return;
36
+ }
37
+ try {
38
+ navigator.vibrate?.(400);
39
+ } catch {
40
+ }
41
+ }
42
+ async setClipboard(text) {
43
+ const clip = getCapacitor()?.Plugins?.Clipboard;
44
+ if (clip?.write) {
45
+ await clip.write({ string: text });
46
+ return;
47
+ }
48
+ if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(text);
49
+ }
50
+ async getClipboard() {
51
+ const clip = getCapacitor()?.Plugins?.Clipboard;
52
+ if (clip?.read) {
53
+ const res = await clip.read();
54
+ return res?.value ?? "";
55
+ }
56
+ if (navigator.clipboard?.readText) return navigator.clipboard.readText();
57
+ return "";
58
+ }
59
+ async share(payload) {
60
+ const share = getCapacitor()?.Plugins?.Share;
61
+ const url = typeof location !== "undefined" ? location.href + (payload.query ? `?${payload.query}` : "") : payload.imageUrl;
62
+ if (share?.share) {
63
+ await share.share({ title: payload.title, url });
64
+ return;
65
+ }
66
+ const navAny = navigator;
67
+ if (navAny.share) {
68
+ await navAny.share({ title: payload.title, url });
69
+ return;
70
+ }
71
+ throw new PlatformUnsupportedError("capacitor", "device.share");
72
+ }
73
+ };
74
+ var CapacitorLifecycle = class {
75
+ constructor(getLaunchOptions) {
76
+ __publicField(this, "domLifecycle");
77
+ __publicField(this, "getLaunch");
78
+ this.getLaunch = getLaunchOptions;
79
+ this.domLifecycle = new DomLifecycle(getLaunchOptions);
80
+ }
81
+ onShow(cb) {
82
+ const app = getCapacitor()?.Plugins?.App;
83
+ if (app?.addListener) {
84
+ const handle = app.addListener("appStateChange", (state) => {
85
+ if (state.isActive) cb(this.getLaunch());
86
+ });
87
+ return makeRemove(handle);
88
+ }
89
+ return this.domLifecycle.onShow(cb);
90
+ }
91
+ onHide(cb) {
92
+ const app = getCapacitor()?.Plugins?.App;
93
+ if (app?.addListener) {
94
+ const handle = app.addListener("appStateChange", (state) => {
95
+ if (!state.isActive) cb();
96
+ });
97
+ return makeRemove(handle);
98
+ }
99
+ return this.domLifecycle.onHide(cb);
100
+ }
101
+ };
102
+ function makeRemove(handle) {
103
+ let resolved;
104
+ let removedEarly = false;
105
+ if (handle instanceof Promise) {
106
+ void handle.then((h) => {
107
+ if (removedEarly) h.remove();
108
+ else resolved = h;
109
+ });
110
+ } else {
111
+ resolved = handle;
112
+ }
113
+ return () => {
114
+ if (resolved) resolved.remove();
115
+ else removedEarly = true;
116
+ };
117
+ }
118
+ var CapacitorPlatform = class extends BasePlatform {
119
+ constructor() {
120
+ super(...arguments);
121
+ __publicField(this, "platformName", "capacitor");
122
+ __publicField(this, "isMiniGame", false);
123
+ // device 提供;ads/payment 由具体游戏接插件后扩展,核心层保持 undefined
124
+ __publicField(this, "device", new CapacitorDevice());
125
+ __publicField(this, "lifecycle", new CapacitorLifecycle(
126
+ () => this.getLaunchOptions()
127
+ ));
128
+ }
129
+ async init() {
130
+ this.readDomSystemInfo();
131
+ this.readDomLaunchOptions();
132
+ const cap = getCapacitor();
133
+ if (cap && isNative()) {
134
+ try {
135
+ const p = cap.getPlatform();
136
+ if (p === "ios" || p === "android") {
137
+ this._system = { ...this._system, os: p };
138
+ }
139
+ } catch {
140
+ }
141
+ }
142
+ }
143
+ };
144
+
145
+ export { CapacitorPlatform };
@@ -0,0 +1,33 @@
1
+ import { p as PlatformName, m as IPlatformStorage, g as IPlatformAuth, e as IPlatformAds, k as IPlatformPayment, h as IPlatformDevice, i as IPlatformLifecycle } from '../types-DtcRFbM0.js';
2
+ import { B as BasePlatform } from '../BasePlatform-BCOkvvDW.js';
3
+
4
+ /**
5
+ * Facebook Instant Games 平台适配器。
6
+ *
7
+ * - hasDOM=true(Instant Games 运行在 webview), isMiniGame=true
8
+ * - net:fetch + 标准 WebSocket(继承 BasePlatform)
9
+ * - storage:FBInstant.player KV(getDataAsync/setDataAsync)是异步 KV,
10
+ * 而 IPlatformStorage 是同步接口 —— 采用"内存缓存 + 异步回写"策略:
11
+ * init 时预拉一份到内存,getItem 读缓存,setItem 写缓存并异步 flush。
12
+ * - lifecycle:onShow 退回 DOM visibilitychange(FB 无 onResume,只有 onPause);onHide 用 FBInstant.onPause
13
+ * - auth:FBInstant.player(getID/getName/getPhoto)+ getSignedPlayerInfoAsync 作为 code
14
+ * - ads:getRewardedVideoAsync(loadAsync → showAsync);插屏同理
15
+ * - payment:FBInstant.payments
16
+ *
17
+ * init 流程:initializeAsync() → 上报加载进度 → startGameAsync() → 预拉存储。
18
+ */
19
+
20
+ declare class FacebookPlatform extends BasePlatform {
21
+ readonly platformName: PlatformName;
22
+ readonly isMiniGame = true;
23
+ private readonly fbStorage;
24
+ readonly storage: IPlatformStorage;
25
+ readonly auth: IPlatformAuth;
26
+ readonly ads: IPlatformAds;
27
+ readonly payment: IPlatformPayment;
28
+ readonly device: IPlatformDevice;
29
+ readonly lifecycle: IPlatformLifecycle;
30
+ init(): Promise<void>;
31
+ }
32
+
33
+ export { FacebookPlatform };
@@ -0,0 +1,256 @@
1
+ import { BasePlatform, DomLifecycle } from '../chunk-H5CUVYCN.js';
2
+ import { PlatformUnsupportedError } from '../chunk-II3JM4R3.js';
3
+ import { __publicField } from '../chunk-PKBMQBKP.js';
4
+
5
+ // src/platform/impl/facebook/FacebookPlatform.ts
6
+ function hasFB() {
7
+ return typeof FBInstant !== "undefined";
8
+ }
9
+ function requireFB(capability) {
10
+ if (!hasFB()) throw new PlatformUnsupportedError("facebook", capability);
11
+ }
12
+ var _FacebookStorage = class _FacebookStorage {
13
+ constructor() {
14
+ /** 内存缓存:key -> value(string) */
15
+ __publicField(this, "cache", /* @__PURE__ */ new Map());
16
+ /** 待回写的脏 key */
17
+ __publicField(this, "dirty", /* @__PURE__ */ new Set());
18
+ __publicField(this, "flushTimer");
19
+ __publicField(this, "hydrated", false);
20
+ }
21
+ /** init 阶段调用:预拉整份 KV 到内存 */
22
+ async hydrate() {
23
+ if (!hasFB()) {
24
+ this.hydrated = true;
25
+ return;
26
+ }
27
+ try {
28
+ const data = await FBInstant.player.getDataAsync([_FacebookStorage.RECORD_KEY]);
29
+ const record = data?.[_FacebookStorage.RECORD_KEY];
30
+ if (record && typeof record === "object") {
31
+ for (const [k, v] of Object.entries(record)) {
32
+ this.cache.set(k, String(v));
33
+ }
34
+ }
35
+ } catch {
36
+ }
37
+ this.hydrated = true;
38
+ }
39
+ getItem(key) {
40
+ const v = this.cache.get(key);
41
+ return v === void 0 ? null : v;
42
+ }
43
+ setItem(key, value) {
44
+ this.cache.set(key, value);
45
+ this.dirty.add(key);
46
+ this.scheduleFlush();
47
+ }
48
+ removeItem(key) {
49
+ this.cache.delete(key);
50
+ this.dirty.add(key);
51
+ this.scheduleFlush();
52
+ }
53
+ clear() {
54
+ for (const k of this.cache.keys()) this.dirty.add(k);
55
+ this.cache.clear();
56
+ this.scheduleFlush();
57
+ }
58
+ /** 去抖:合并短时间内的多次写,统一异步回写 FB KV */
59
+ scheduleFlush() {
60
+ if (!hasFB()) return;
61
+ if (this.flushTimer) clearTimeout(this.flushTimer);
62
+ this.flushTimer = setTimeout(() => void this.flush(), 300);
63
+ }
64
+ async flush() {
65
+ if (!hasFB() || this.dirty.size === 0) return;
66
+ this.dirty.clear();
67
+ const record = {};
68
+ for (const [k, v] of this.cache.entries()) record[k] = v;
69
+ try {
70
+ await FBInstant.player.setDataAsync({ [_FacebookStorage.RECORD_KEY]: record });
71
+ await FBInstant.player.flushDataAsync?.();
72
+ } catch {
73
+ }
74
+ }
75
+ };
76
+ /** 存入 FB KV 时的统一外层 key(单条 record 装整个字典,减少 KV 配额占用) */
77
+ __publicField(_FacebookStorage, "RECORD_KEY", "__fw_kv__");
78
+ var FacebookStorage = _FacebookStorage;
79
+ var FacebookAuth = class {
80
+ async login() {
81
+ requireFB("auth.login");
82
+ const info = await FBInstant.player.getSignedPlayerInfoAsync();
83
+ return {
84
+ code: info.getSignature(),
85
+ openId: info.getPlayerID(),
86
+ raw: info
87
+ };
88
+ }
89
+ async getProfile() {
90
+ requireFB("auth.getProfile");
91
+ const name = FBInstant.player.getName();
92
+ const photo = FBInstant.player.getPhoto();
93
+ if (!name && !photo) return null;
94
+ return { nickname: name ?? "", avatarUrl: photo ?? "" };
95
+ }
96
+ };
97
+ var FacebookAds = class {
98
+ constructor() {
99
+ __publicField(this, "rewarded");
100
+ __publicField(this, "interstitial");
101
+ }
102
+ async preloadRewarded(adUnitId) {
103
+ requireFB("ads.preloadRewarded");
104
+ if (!adUnitId)
105
+ throw new PlatformUnsupportedError("facebook", "ads.preloadRewarded(\u7F3A\u5C11 placementId)");
106
+ this.rewarded = await FBInstant.getRewardedVideoAsync(adUnitId);
107
+ await this.rewarded.loadAsync();
108
+ }
109
+ async showRewarded(adUnitId) {
110
+ requireFB("ads.showRewarded");
111
+ try {
112
+ if (!this.rewarded || adUnitId && this.rewarded.getPlacementID() !== adUnitId) {
113
+ if (!adUnitId)
114
+ throw new PlatformUnsupportedError("facebook", "ads.showRewarded(\u7F3A\u5C11 placementId)");
115
+ this.rewarded = await FBInstant.getRewardedVideoAsync(adUnitId);
116
+ await this.rewarded.loadAsync();
117
+ }
118
+ await this.rewarded.showAsync();
119
+ this.rewarded = void 0;
120
+ return "completed";
121
+ } catch {
122
+ this.rewarded = void 0;
123
+ return "failed";
124
+ }
125
+ }
126
+ async showInterstitial(adUnitId) {
127
+ requireFB("ads.showInterstitial");
128
+ try {
129
+ if (!this.interstitial || adUnitId && this.interstitial.getPlacementID() !== adUnitId) {
130
+ if (!adUnitId)
131
+ throw new PlatformUnsupportedError(
132
+ "facebook",
133
+ "ads.showInterstitial(\u7F3A\u5C11 placementId)"
134
+ );
135
+ this.interstitial = await FBInstant.getInterstitialAdAsync(adUnitId);
136
+ await this.interstitial.loadAsync();
137
+ }
138
+ await this.interstitial.showAsync();
139
+ this.interstitial = void 0;
140
+ return "closed";
141
+ } catch {
142
+ this.interstitial = void 0;
143
+ return "failed";
144
+ }
145
+ }
146
+ };
147
+ var FacebookPayment = class {
148
+ async purchase(productId, extra) {
149
+ requireFB("payment.purchase");
150
+ const developerPayload = extra && typeof extra.developerPayload === "string" ? extra.developerPayload : void 0;
151
+ const p = await FBInstant.payments.purchaseAsync({ productID: productId, developerPayload });
152
+ return {
153
+ productId: p.productID,
154
+ transactionId: p.paymentID ?? p.purchaseToken,
155
+ receipt: p.signedRequest,
156
+ raw: p
157
+ };
158
+ }
159
+ async restore() {
160
+ requireFB("payment.restore");
161
+ const list = await FBInstant.payments.getPurchasesAsync();
162
+ return (list ?? []).map((p) => ({
163
+ productId: p.productID,
164
+ transactionId: p.paymentID ?? p.purchaseToken,
165
+ receipt: p.signedRequest,
166
+ raw: p
167
+ }));
168
+ }
169
+ };
170
+ var FacebookDevice = class {
171
+ vibrateShort() {
172
+ try {
173
+ navigator.vibrate?.(15);
174
+ } catch {
175
+ }
176
+ }
177
+ vibrateLong() {
178
+ try {
179
+ navigator.vibrate?.(400);
180
+ } catch {
181
+ }
182
+ }
183
+ async setClipboard(text) {
184
+ if (navigator.clipboard?.writeText) await navigator.clipboard.writeText(text);
185
+ }
186
+ async getClipboard() {
187
+ if (navigator.clipboard?.readText) return navigator.clipboard.readText();
188
+ return "";
189
+ }
190
+ async share(payload) {
191
+ requireFB("device.share");
192
+ await FBInstant.shareAsync({
193
+ intent: "SHARE",
194
+ image: payload.imageUrl,
195
+ text: payload.title,
196
+ data: payload.query ? { query: payload.query } : void 0
197
+ });
198
+ }
199
+ };
200
+ var FacebookLifecycle = class {
201
+ constructor(getLaunchOptions) {
202
+ __publicField(this, "domLifecycle");
203
+ this.domLifecycle = new DomLifecycle(getLaunchOptions);
204
+ }
205
+ onShow(cb) {
206
+ return this.domLifecycle.onShow(cb);
207
+ }
208
+ onHide(cb) {
209
+ if (hasFB()) {
210
+ FBInstant.onPause(() => cb());
211
+ return this.domLifecycle.onHide(cb);
212
+ }
213
+ return this.domLifecycle.onHide(cb);
214
+ }
215
+ };
216
+ var FacebookPlatform = class extends BasePlatform {
217
+ constructor() {
218
+ super(...arguments);
219
+ __publicField(this, "platformName", "facebook");
220
+ __publicField(this, "isMiniGame", true);
221
+ __publicField(this, "fbStorage", new FacebookStorage());
222
+ __publicField(this, "storage", this.fbStorage);
223
+ __publicField(this, "auth", new FacebookAuth());
224
+ __publicField(this, "ads", new FacebookAds());
225
+ __publicField(this, "payment", new FacebookPayment());
226
+ __publicField(this, "device", new FacebookDevice());
227
+ __publicField(this, "lifecycle", new FacebookLifecycle(
228
+ () => this.getLaunchOptions()
229
+ ));
230
+ }
231
+ async init() {
232
+ this.readDomSystemInfo();
233
+ this.readDomLaunchOptions();
234
+ if (hasFB()) {
235
+ await FBInstant.initializeAsync();
236
+ FBInstant.setLoadingProgress(100);
237
+ await FBInstant.startGameAsync();
238
+ try {
239
+ this._system = { ...this._system, language: FBInstant.getLocale() };
240
+ } catch {
241
+ }
242
+ try {
243
+ const entry = FBInstant.getEntryPointData();
244
+ if (entry && typeof entry === "object") {
245
+ const query = { ...this._launchOptions.query };
246
+ for (const [k, v] of Object.entries(entry)) query[k] = String(v);
247
+ this._launchOptions = { ...this._launchOptions, query, raw: entry };
248
+ }
249
+ } catch {
250
+ }
251
+ await this.fbStorage.hydrate();
252
+ }
253
+ }
254
+ };
255
+
256
+ export { FacebookPlatform };
@@ -0,0 +1,30 @@
1
+ import { p as PlatformName, g as IPlatformAuth, e as IPlatformAds, k as IPlatformPayment, h as IPlatformDevice, f as IPlatformAnalytics, i as IPlatformLifecycle } from '../types-DtcRFbM0.js';
2
+ import { B as BasePlatform } from '../BasePlatform-BCOkvvDW.js';
3
+
4
+ /**
5
+ * TikTok Mini Games(Minis)平台适配器。
6
+ *
7
+ * - hasDOM=true(HTML 运行时,真 webview), isMiniGame=true
8
+ * - net:fetch + 标准 WebSocket(webview 支持,继承 BasePlatform)
9
+ * - storage:localStorage(继承 BasePlatform)
10
+ * - lifecycle:优先用 TTMinis.game.onShow/onHide,缺失时退回 DOM visibilitychange
11
+ * - device:vibrate / clipboard / share 必须走 TTMinis 桥接(TikTok 禁用对应 Web API)
12
+ * - auth / ads / payment / analytics:全部走 TTMinis.game
13
+ *
14
+ * 所有 TTMinis 调用前判断 `typeof TTMinis !== 'undefined'`,缺失则抛 PlatformUnsupportedError
15
+ * 或优雅降级。SDK 由构建侧通过 <script src=".../minis.js"> 注入。
16
+ */
17
+
18
+ declare class TikTokPlatform extends BasePlatform {
19
+ readonly platformName: PlatformName;
20
+ readonly isMiniGame = true;
21
+ readonly auth: IPlatformAuth;
22
+ readonly ads: IPlatformAds;
23
+ readonly payment: IPlatformPayment;
24
+ readonly device: IPlatformDevice;
25
+ readonly analytics: IPlatformAnalytics;
26
+ readonly lifecycle: IPlatformLifecycle;
27
+ init(): Promise<void>;
28
+ }
29
+
30
+ export { TikTokPlatform };
@@ -0,0 +1,170 @@
1
+ import { BasePlatform } from '../chunk-H5CUVYCN.js';
2
+ import { PlatformUnsupportedError } from '../chunk-II3JM4R3.js';
3
+ import { __publicField } from '../chunk-PKBMQBKP.js';
4
+
5
+ // src/platform/impl/tiktok/TikTokPlatform.ts
6
+ function hasTT() {
7
+ return typeof TTMinis !== "undefined" && !!TTMinis.game;
8
+ }
9
+ function requireTT(capability) {
10
+ if (!hasTT()) throw new PlatformUnsupportedError("tiktok", capability);
11
+ }
12
+ var TikTokAuth = class {
13
+ async login() {
14
+ requireTT("auth.login");
15
+ const res = await TTMinis.game.login();
16
+ return { code: res.code, openId: res.openId, raw: res };
17
+ }
18
+ async getProfile() {
19
+ requireTT("auth.getProfile");
20
+ const info = await TTMinis.game.getUserInfo();
21
+ if (!info) return null;
22
+ return { nickname: info.nickName ?? "", avatarUrl: info.avatarUrl ?? "" };
23
+ }
24
+ };
25
+ var TikTokAds = class {
26
+ async preloadRewarded(adUnitId) {
27
+ requireTT("ads.preloadRewarded");
28
+ await TTMinis.game.preloadRewardedVideo(adUnitId ? { adUnitId } : void 0);
29
+ }
30
+ async showRewarded(adUnitId) {
31
+ requireTT("ads.showRewarded");
32
+ try {
33
+ const res = await TTMinis.game.showRewardedVideo(adUnitId ? { adUnitId } : void 0);
34
+ return res?.isEnded ? "completed" : "skipped";
35
+ } catch {
36
+ return "failed";
37
+ }
38
+ }
39
+ async showInterstitial(adUnitId) {
40
+ requireTT("ads.showInterstitial");
41
+ try {
42
+ await TTMinis.game.showInterstitialAd(adUnitId ? { adUnitId } : void 0);
43
+ return "closed";
44
+ } catch {
45
+ return "failed";
46
+ }
47
+ }
48
+ };
49
+ var TikTokPayment = class {
50
+ async purchase(productId, extra) {
51
+ requireTT("payment.purchase");
52
+ const res = await TTMinis.game.requestPayment({ productId, ...extra ?? {} });
53
+ return {
54
+ productId: res.productId ?? productId,
55
+ transactionId: res.transactionId ?? "",
56
+ receipt: res.receipt ?? "",
57
+ raw: res
58
+ };
59
+ }
60
+ async restore() {
61
+ requireTT("payment.restore");
62
+ const fn = TTMinis.game.getUnfinishedPurchases;
63
+ if (!fn) return [];
64
+ const list = await fn.call(TTMinis.game) ?? [];
65
+ return list.map((res) => ({
66
+ productId: res.productId,
67
+ transactionId: res.transactionId ?? "",
68
+ receipt: res.receipt ?? "",
69
+ raw: res
70
+ }));
71
+ }
72
+ };
73
+ var TikTokDevice = class {
74
+ vibrateShort() {
75
+ if (!hasTT()) return;
76
+ TTMinis.game.vibrateShort();
77
+ }
78
+ vibrateLong() {
79
+ if (!hasTT()) return;
80
+ TTMinis.game.vibrateLong();
81
+ }
82
+ async setClipboard(text) {
83
+ requireTT("device.setClipboard");
84
+ await TTMinis.game.setClipboardData({ data: text });
85
+ }
86
+ async getClipboard() {
87
+ requireTT("device.getClipboard");
88
+ const res = await TTMinis.game.getClipboardData();
89
+ return res?.data ?? "";
90
+ }
91
+ async share(payload) {
92
+ requireTT("device.share");
93
+ await TTMinis.game.shareAppMessage({
94
+ title: payload.title,
95
+ imageUrl: payload.imageUrl,
96
+ query: payload.query
97
+ });
98
+ }
99
+ };
100
+ var TikTokAnalytics = class {
101
+ reportEvent(name, params) {
102
+ if (!hasTT()) return;
103
+ TTMinis.game.reportEvent(name, params);
104
+ }
105
+ };
106
+ var TikTokLifecycle = class {
107
+ onShow(cb) {
108
+ if (!hasTT()) return () => {
109
+ };
110
+ const handler = (res) => {
111
+ cb({ scene: res?.scene, query: res?.query ?? {}, raw: res });
112
+ };
113
+ TTMinis.game.onShow(handler);
114
+ return () => TTMinis.game.offShow?.(handler);
115
+ }
116
+ onHide(cb) {
117
+ if (!hasTT()) return () => {
118
+ };
119
+ const handler = () => cb();
120
+ TTMinis.game.onHide(handler);
121
+ return () => TTMinis.game.offHide?.(handler);
122
+ }
123
+ };
124
+ var TikTokPlatform = class extends BasePlatform {
125
+ constructor() {
126
+ super(...arguments);
127
+ __publicField(this, "platformName", "tiktok");
128
+ __publicField(this, "isMiniGame", true);
129
+ __publicField(this, "auth", new TikTokAuth());
130
+ __publicField(this, "ads", new TikTokAds());
131
+ __publicField(this, "payment", new TikTokPayment());
132
+ __publicField(this, "device", new TikTokDevice());
133
+ __publicField(this, "analytics", new TikTokAnalytics());
134
+ // 用 TTMinis 桥接的生命周期,缺失时由其内部退回 noop;DOM 退路在 init 中按需补
135
+ __publicField(this, "lifecycle", new TikTokLifecycle());
136
+ }
137
+ async init() {
138
+ this.readDomSystemInfo();
139
+ this.readDomLaunchOptions();
140
+ if (hasTT()) {
141
+ const sysFn = TTMinis.game.getSystemInfoSync;
142
+ if (sysFn) {
143
+ const sys = sysFn.call(TTMinis.game);
144
+ this._system = {
145
+ screenWidth: sys.screenWidth ?? this._system.screenWidth,
146
+ screenHeight: sys.screenHeight ?? this._system.screenHeight,
147
+ pixelRatio: sys.pixelRatio ?? this._system.pixelRatio,
148
+ os: sys.platform ?? this._system.os,
149
+ language: sys.language ?? this._system.language,
150
+ hostVersion: sys.version ?? this._system.hostVersion
151
+ };
152
+ if (sys.safeArea) {
153
+ this._safeArea = {
154
+ top: sys.safeArea.top,
155
+ bottom: sys.safeArea.bottom,
156
+ left: sys.safeArea.left,
157
+ right: sys.safeArea.right
158
+ };
159
+ }
160
+ }
161
+ const launchFn = TTMinis.game.getLaunchOptionsSync;
162
+ if (launchFn) {
163
+ const lo = launchFn.call(TTMinis.game);
164
+ this._launchOptions = { scene: lo.scene, query: lo.query ?? {}, raw: lo };
165
+ }
166
+ }
167
+ }
168
+ };
169
+
170
+ export { TikTokPlatform };
@@ -0,0 +1,22 @@
1
+ import { p as PlatformName, h as IPlatformDevice } from '../types-DtcRFbM0.js';
2
+ import { B as BasePlatform } from '../BasePlatform-BCOkvvDW.js';
3
+
4
+ /**
5
+ * Web(普通浏览器 / H5)平台适配器。
6
+ *
7
+ * - hasDOM=true, isMiniGame=false
8
+ * - net:fetch + 标准 WebSocket(继承 BasePlatform)
9
+ * - storage:localStorage(继承 BasePlatform)
10
+ * - lifecycle:document.visibilitychange(继承 BasePlatform)
11
+ * - device:navigator.vibrate / navigator.clipboard / Web Share API
12
+ * - 无 auth / ads / payment(浏览器无统一登录/广告/内购体系,保持 undefined)
13
+ */
14
+
15
+ declare class WebPlatform extends BasePlatform {
16
+ readonly platformName: PlatformName;
17
+ readonly isMiniGame = false;
18
+ readonly device: IPlatformDevice;
19
+ init(): Promise<void>;
20
+ }
21
+
22
+ export { WebPlatform };