@lark-apaas/client-toolkit-lite 1.1.7-alpha.7 → 1.1.7-alpha.8

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.cjs CHANGED
@@ -59,6 +59,7 @@ __export(index_exports, {
59
59
  isIpad: () => isIpad,
60
60
  isMobile: () => isMobile,
61
61
  isPreview: () => isPreview,
62
+ logger: () => logger,
62
63
  normalizeBasePath: () => normalizeBasePath,
63
64
  reportTeaEvent: () => reportTeaEvent,
64
65
  resolveAppUrl: () => resolveAppUrl,
@@ -72,7 +73,7 @@ __export(index_exports, {
72
73
  module.exports = __toCommonJS(index_exports);
73
74
 
74
75
  // src/components/AppContainer/index.tsx
75
- var import_react7 = __toESM(require("react"), 1);
76
+ var import_react9 = __toESM(require("react"), 1);
76
77
  var import_miaoda_inspector = require("@lark-apaas/miaoda-inspector");
77
78
 
78
79
  // src/runtime/react-devtools-hook.ts
@@ -129,15 +130,15 @@ function initAxiosConfig(axiosInstance2) {
129
130
  if (!axiosInstance2) {
130
131
  axiosInstance2 = import_axios.default;
131
132
  }
132
- axiosInstance2.interceptors.request.use((config) => {
133
+ axiosInstance2.interceptors.request.use((config2) => {
133
134
  const csrfToken = getCsrfToken();
134
135
  if (csrfToken) {
135
- config.headers["X-Suda-Csrf-Token"] = csrfToken;
136
+ config2.headers["X-Suda-Csrf-Token"] = csrfToken;
136
137
  }
137
138
  if (typeof window !== "undefined") {
138
- config.headers["X-Page-Route"] = window.location.pathname;
139
+ config2.headers["X-Page-Route"] = window.location.pathname;
139
140
  }
140
- return config;
141
+ return config2;
141
142
  }, (error) => Promise.reject(error));
142
143
  axiosInstance2.interceptors.response.use((response) => response, (error) => {
143
144
  if (process.env.NODE_ENV !== "production") {
@@ -148,10 +149,694 @@ function initAxiosConfig(axiosInstance2) {
148
149
  }
149
150
  __name(initAxiosConfig, "initAxiosConfig");
150
151
 
152
+ // src/logger/logger.ts
153
+ var import_observable_web = require("@lark-apaas/observable-web");
154
+
155
+ // src/utils/hmr-api.ts
156
+ var import_meta = {};
157
+ function createWebpackHmrApi(hot) {
158
+ return {
159
+ onSuccess(callback) {
160
+ let lastStatus = null;
161
+ const handler = /* @__PURE__ */ __name((status) => {
162
+ if (status === "idle" && lastStatus === "apply") {
163
+ try {
164
+ callback();
165
+ } catch (e) {
166
+ console.error("[HMR] Success callback error:", e);
167
+ }
168
+ }
169
+ lastStatus = status;
170
+ }, "handler");
171
+ hot.addStatusHandler(handler);
172
+ return () => hot.removeStatusHandler(handler);
173
+ },
174
+ onError(callback) {
175
+ const handler = /* @__PURE__ */ __name((status) => {
176
+ if (status === "fail" || status === "abort") {
177
+ try {
178
+ callback(new Error(`HMR ${status}`));
179
+ } catch (e) {
180
+ console.error("[HMR] Error callback error:", e);
181
+ }
182
+ }
183
+ }, "handler");
184
+ hot.addStatusHandler(handler);
185
+ return () => hot.removeStatusHandler(handler);
186
+ }
187
+ };
188
+ }
189
+ __name(createWebpackHmrApi, "createWebpackHmrApi");
190
+ function getHmrApi() {
191
+ if (process.env.NODE_ENV === "production") return null;
192
+ if (import_meta.webpackHot) {
193
+ return createWebpackHmrApi(import_meta.webpackHot);
194
+ }
195
+ if (typeof module !== "undefined" && module.hot) {
196
+ return createWebpackHmrApi(module.hot);
197
+ }
198
+ if (window.__VITE_HMR__) {
199
+ return window.__VITE_HMR__;
200
+ }
201
+ return null;
202
+ }
203
+ __name(getHmrApi, "getHmrApi");
204
+
205
+ // src/utils/postMessage.ts
206
+ var PARENT_ORIGIN_KEY = "__parentOrigin";
207
+ function getParentOriginFromParams() {
208
+ try {
209
+ const params = new URLSearchParams(window.location.search);
210
+ const origin = params.get(PARENT_ORIGIN_KEY);
211
+ if (origin) {
212
+ sessionStorage.setItem(PARENT_ORIGIN_KEY, origin);
213
+ return origin;
214
+ }
215
+ } catch {
216
+ }
217
+ try {
218
+ return sessionStorage.getItem(PARENT_ORIGIN_KEY) || void 0;
219
+ } catch {
220
+ return void 0;
221
+ }
222
+ }
223
+ __name(getParentOriginFromParams, "getParentOriginFromParams");
224
+ function getLegacyParentOrigin() {
225
+ const { origin } = window.location;
226
+ if (origin.includes("force.feishuapp.net")) {
227
+ return "https://force.feishu.cn";
228
+ }
229
+ if (origin.includes("force-pre.feishuapp.net")) {
230
+ return "https://force.feishu-pre.cn";
231
+ }
232
+ if (origin.includes("force.byted.org")) {
233
+ return "https://force.feishu-boe.cn";
234
+ }
235
+ if (origin.includes("feishuapp.cn") || origin.includes("miaoda.feishuapp.net")) {
236
+ return "https://miaoda.feishu.cn";
237
+ }
238
+ if (origin.includes("fsapp.kundou.cn") || origin.includes("miaoda-pre.feishuapp.net")) {
239
+ return "https://miaoda.feishu-pre.cn";
240
+ }
241
+ return "https://miaoda.feishu-boe.cn";
242
+ }
243
+ __name(getLegacyParentOrigin, "getLegacyParentOrigin");
244
+ function resolveParentOrigin() {
245
+ try {
246
+ if (document.referrer) {
247
+ const referrerOrigin = new URL(document.referrer).origin;
248
+ if (referrerOrigin.startsWith("http://localhost") || referrerOrigin.startsWith("http://127.0.0.1")) {
249
+ return referrerOrigin;
250
+ }
251
+ }
252
+ } catch {
253
+ }
254
+ const paramOrigin = getParentOriginFromParams();
255
+ if (paramOrigin) return paramOrigin;
256
+ return process.env?.FORCE_FRAMEWORK_DOMAIN_MAIN ?? getLegacyParentOrigin();
257
+ }
258
+ __name(resolveParentOrigin, "resolveParentOrigin");
259
+ function submitPostMessage(message, targetOrigin) {
260
+ try {
261
+ const parentOrigin = resolveParentOrigin();
262
+ const origin = targetOrigin ?? parentOrigin;
263
+ if (!origin) return;
264
+ window.parent.postMessage(message, origin);
265
+ } catch (e) {
266
+ console.error("postMessage error", e);
267
+ }
268
+ }
269
+ __name(submitPostMessage, "submitPostMessage");
270
+
271
+ // src/logger/log-types.ts
272
+ var LOG_LEVELS = [
273
+ "debug",
274
+ "info",
275
+ "warn",
276
+ "error",
277
+ "success"
278
+ ];
279
+ function isLogLevel(value) {
280
+ return typeof value === "string" && LOG_LEVELS.includes(value);
281
+ }
282
+ __name(isLogLevel, "isLogLevel");
283
+
284
+ // src/logger/intercept-global-error.ts
285
+ var devServerDisconnectInfo = null;
286
+ var retryCount = 0;
287
+ function processDevServerLog(log) {
288
+ if (!log) return;
289
+ const devFlag = log.includes("[webpack-dev-server]") || log.includes("[vite]");
290
+ if (devFlag && log.includes("Disconnected")) {
291
+ const time = Date.now();
292
+ devServerDisconnectInfo = {
293
+ time
294
+ };
295
+ submitPostMessage({
296
+ type: "DevServerMessage",
297
+ data: {
298
+ type: "devServer-status",
299
+ status: "disconnected"
300
+ }
301
+ });
302
+ return;
303
+ }
304
+ if (!devServerDisconnectInfo) {
305
+ return;
306
+ }
307
+ if (devFlag && log.includes("Trying to reconnect")) {
308
+ retryCount++;
309
+ return;
310
+ }
311
+ const hmrFlag = log.includes("[HMR]");
312
+ if (hmrFlag || devFlag && (log.includes("Socket connected") || log.includes("App updated") || log.includes("App hot update") || log.includes("connected"))) {
313
+ submitPostMessage({
314
+ type: "DevServerMessage",
315
+ data: {
316
+ type: "devServer-status",
317
+ status: "connected"
318
+ }
319
+ });
320
+ devServerDisconnectInfo = null;
321
+ retryCount = 0;
322
+ }
323
+ }
324
+ __name(processDevServerLog, "processDevServerLog");
325
+ function listenModuleHmr() {
326
+ const hmr = getHmrApi();
327
+ if (hmr) {
328
+ hmr.onSuccess(() => {
329
+ submitPostMessage({
330
+ type: "DevServerMessage",
331
+ data: {
332
+ type: "devServer-status",
333
+ status: "hmr-apply-success"
334
+ }
335
+ });
336
+ });
337
+ hmr.onError((error) => {
338
+ console.warn("hmr apply failed", error);
339
+ });
340
+ }
341
+ }
342
+ __name(listenModuleHmr, "listenModuleHmr");
343
+ var PROXY_CONSOLE_METHOD = [
344
+ "log",
345
+ "info",
346
+ "warn",
347
+ "error"
348
+ ];
349
+ function interceptErrors() {
350
+ window.addEventListener("error", (event) => {
351
+ logger.error(event.error);
352
+ });
353
+ window.addEventListener("unhandledrejection", (event) => {
354
+ logger.error(event.reason);
355
+ });
356
+ listenModuleHmr();
357
+ PROXY_CONSOLE_METHOD.forEach((method) => {
358
+ const originalMethod = window.console[method];
359
+ window.console[method] = (...args) => {
360
+ originalMethod(...args);
361
+ const level = method === "log" ? "info" : method;
362
+ const first = args[0];
363
+ if (typeof first === "string") {
364
+ processDevServerLog(first);
365
+ }
366
+ if (typeof first === "string" && first.startsWith("[Dataloom]") && isLogLevel(level)) {
367
+ logger.log({
368
+ level,
369
+ args
370
+ });
371
+ submitPostMessage({
372
+ type: "Console",
373
+ method,
374
+ data: args
375
+ });
376
+ }
377
+ };
378
+ });
379
+ }
380
+ __name(interceptErrors, "interceptErrors");
381
+
382
+ // src/utils/safeStringify.ts
383
+ function safeStringify(obj) {
384
+ const seen = /* @__PURE__ */ new Set();
385
+ try {
386
+ return JSON.stringify(obj, (_key, value) => {
387
+ if (typeof value === "object" && value !== null) {
388
+ if (seen.has(value)) {
389
+ return "[Circular]";
390
+ }
391
+ seen.add(value);
392
+ }
393
+ if (typeof value === "bigint") {
394
+ return value.toString();
395
+ }
396
+ if (value instanceof Date) {
397
+ return value.toISOString();
398
+ }
399
+ if (value instanceof Map) {
400
+ return Object.fromEntries(value);
401
+ }
402
+ if (value instanceof Set) {
403
+ return Array.from(value);
404
+ }
405
+ if (value instanceof Error) {
406
+ return {
407
+ name: value.name,
408
+ message: value.message,
409
+ stack: value.stack
410
+ };
411
+ }
412
+ if (typeof value === "undefined") {
413
+ return "undefined";
414
+ }
415
+ if (typeof value === "symbol") {
416
+ return value.toString();
417
+ }
418
+ return value;
419
+ });
420
+ } catch {
421
+ return "";
422
+ } finally {
423
+ seen.clear();
424
+ }
425
+ }
426
+ __name(safeStringify, "safeStringify");
427
+ function processLogParams(args) {
428
+ return args.map((arg) => {
429
+ if (typeof arg === "string") return arg;
430
+ if (arg instanceof Error) {
431
+ return `${arg.name}: ${arg.message}
432
+ ${arg.stack ?? ""}`;
433
+ }
434
+ if (typeof arg === "object" && arg !== null) {
435
+ return safeStringify(arg);
436
+ }
437
+ return String(arg);
438
+ });
439
+ }
440
+ __name(processLogParams, "processLogParams");
441
+ function mapLogLevel(level) {
442
+ if (level === "warn") return "WARN";
443
+ if (level === "error") return "ERROR";
444
+ return "INFO";
445
+ }
446
+ __name(mapLogLevel, "mapLogLevel");
447
+
448
+ // src/logger/logger.ts
449
+ var shouldReportToObservable = process.env.NODE_ENV === "production";
450
+ var ORDERED_LEVELS = [
451
+ "debug",
452
+ "info",
453
+ "warn",
454
+ "error"
455
+ ];
456
+ var defaultConfig = {
457
+ showLevel: false,
458
+ showTimestamp: false,
459
+ level: "info",
460
+ prefix: ""
461
+ };
462
+ var config = {
463
+ ...defaultConfig
464
+ };
465
+ function configureLogger(options) {
466
+ config = {
467
+ ...defaultConfig,
468
+ ...options
469
+ };
470
+ }
471
+ __name(configureLogger, "configureLogger");
472
+ function shouldLog(level) {
473
+ return ORDERED_LEVELS.indexOf(level) >= ORDERED_LEVELS.indexOf(config.level);
474
+ }
475
+ __name(shouldLog, "shouldLog");
476
+ function getFormattedPrefix(level) {
477
+ const parts = [];
478
+ if (config.prefix) {
479
+ parts.push(`[${config.prefix}]`);
480
+ }
481
+ if (config.showLevel) {
482
+ parts.push(`[${level.toUpperCase()}]`);
483
+ }
484
+ return parts;
485
+ }
486
+ __name(getFormattedPrefix, "getFormattedPrefix");
487
+ configureLogger({
488
+ showLevel: true,
489
+ showTimestamp: false,
490
+ level: process.env.NODE_ENV === "development" ? "debug" : "error",
491
+ prefix: "MiaoDa"
492
+ });
493
+ var logger = {
494
+ debug(message, ...args) {
495
+ if (shouldLog("debug")) {
496
+ console.log(...getFormattedPrefix("debug"), message, ...args);
497
+ }
498
+ },
499
+ info(message, ...args) {
500
+ if (shouldLog("info")) {
501
+ console.log(...getFormattedPrefix("info"), message, ...args);
502
+ }
503
+ if (shouldReportToObservable) {
504
+ import_observable_web.observable.log("INFO", processLogParams([
505
+ message,
506
+ ...args
507
+ ]).join(" "));
508
+ }
509
+ },
510
+ warn(message, ...args) {
511
+ if (shouldLog("warn")) {
512
+ console.log(...getFormattedPrefix("warn"), message, ...args);
513
+ }
514
+ if (shouldReportToObservable) {
515
+ import_observable_web.observable.log("WARN", processLogParams([
516
+ message,
517
+ ...args
518
+ ]).join(" "));
519
+ }
520
+ },
521
+ error(message, ...args) {
522
+ if (shouldLog("error")) {
523
+ console.error(...getFormattedPrefix("error"), message, ...args);
524
+ }
525
+ if (shouldReportToObservable) {
526
+ import_observable_web.observable.log("ERROR", processLogParams([
527
+ message,
528
+ ...args
529
+ ]).join(" "));
530
+ }
531
+ },
532
+ success(message, ...args) {
533
+ if (shouldLog("info")) {
534
+ console.log(...getFormattedPrefix("success"), message, ...args);
535
+ }
536
+ if (shouldReportToObservable) {
537
+ import_observable_web.observable.log("INFO", processLogParams([
538
+ message,
539
+ ...args
540
+ ]).join(" "));
541
+ }
542
+ },
543
+ log({ level, args }) {
544
+ if (shouldLog(level)) {
545
+ console.log(...getFormattedPrefix(level), ...args);
546
+ }
547
+ if (shouldReportToObservable && level !== "debug") {
548
+ import_observable_web.observable.log(mapLogLevel(level), processLogParams(args).join(" "));
549
+ }
550
+ }
551
+ };
552
+ if (process.env.NODE_ENV !== "production") {
553
+ window.__RUNTIME_LOGGER__ = {
554
+ get() {
555
+ return logger;
556
+ }
557
+ };
558
+ }
559
+ if (process.env.NODE_ENV !== "production") {
560
+ interceptErrors();
561
+ }
562
+
563
+ // src/runtime/iframe-bridge.ts
564
+ var import_penpal = require("penpal");
565
+
566
+ // src/logger/batch-logger.ts
567
+ var BatchLogger = class {
568
+ static {
569
+ __name(this, "BatchLogger");
570
+ }
571
+ config;
572
+ logQueue = [];
573
+ flushTimer = null;
574
+ isProcessing = false;
575
+ originConsole;
576
+ constructor(console1, config2) {
577
+ this.originConsole = {
578
+ ...console1
579
+ };
580
+ const { userId = "", tenantId = "", appId = "" } = window || {};
581
+ this.config = {
582
+ userId,
583
+ tenantId,
584
+ appId,
585
+ // 需要加请求路径前缀
586
+ endpoint: (process.env.CLIENT_BASE_PATH || "") + "/dev/logs/collect-batch",
587
+ sizeThreshold: 20,
588
+ flushInterval: 1e3,
589
+ maxRetries: 3,
590
+ retryDelay: 500,
591
+ headers: {
592
+ "Content-Type": "application/json"
593
+ },
594
+ ...config2 || {}
595
+ };
596
+ this.startFlushTimer();
597
+ this.setupBeforeUnloadHandler();
598
+ }
599
+ /**
600
+ * 批量记录日志(对外暴露的唯一方法)
601
+ */
602
+ batchLog(level, message, source) {
603
+ const logEntry = {
604
+ id: this.generateId(),
605
+ level,
606
+ message,
607
+ source,
608
+ timestamp: Date.now()
609
+ };
610
+ this.logQueue.push(logEntry);
611
+ if (this.logQueue.length >= this.config.sizeThreshold) {
612
+ this.flush();
613
+ }
614
+ }
615
+ /**
616
+ * 刷新日志队列,全部发送
617
+ */
618
+ async flush() {
619
+ if (this.isProcessing || this.logQueue.length === 0) {
620
+ return;
621
+ }
622
+ this.isProcessing = true;
623
+ const logsToSend = this.logQueue.splice(0, this.logQueue.length);
624
+ try {
625
+ await this.sendBatch(logsToSend);
626
+ } catch (error) {
627
+ this.logQueue.unshift(...logsToSend);
628
+ } finally {
629
+ this.isProcessing = false;
630
+ }
631
+ }
632
+ /**
633
+ * 发送日志批次到后端
634
+ */
635
+ async sendBatch(logs) {
636
+ const collectLogs = logs.map((log) => ({
637
+ level: log.level,
638
+ message: log.message,
639
+ time: new Date(log.timestamp).toISOString(),
640
+ source: log.source,
641
+ user_id: this.config.userId,
642
+ tenant_id: this.config.tenantId,
643
+ app_id: this.config.appId
644
+ }));
645
+ let retries = 0;
646
+ while (retries <= this.config.maxRetries) {
647
+ try {
648
+ await this.execFetch(this.config.endpoint, {
649
+ method: "POST",
650
+ headers: this.config.headers,
651
+ body: JSON.stringify(collectLogs)
652
+ });
653
+ return;
654
+ } catch (error) {
655
+ retries++;
656
+ if (retries > this.config.maxRetries) {
657
+ this.originConsole.error(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
658
+ } else {
659
+ this.originConsole.warn(`Failed to send logs (attempt ${retries}), retrying in ${this.config.retryDelay}ms...`);
660
+ }
661
+ await this.delay(this.config.retryDelay * retries);
662
+ }
663
+ }
664
+ }
665
+ /**
666
+ * 执行实际的fetch请求
667
+ */
668
+ async execFetch(url, options) {
669
+ return fetch(url, options);
670
+ }
671
+ /**
672
+ * 启动自动刷新定时器
673
+ */
674
+ startFlushTimer() {
675
+ if (this.flushTimer) {
676
+ clearInterval(this.flushTimer);
677
+ }
678
+ this.flushTimer = setInterval(() => {
679
+ if (this.logQueue.length > 0) {
680
+ this.flush();
681
+ }
682
+ }, this.config.flushInterval);
683
+ }
684
+ /**
685
+ * 设置页面卸载时的处理
686
+ */
687
+ setupBeforeUnloadHandler() {
688
+ if (typeof window !== "undefined") {
689
+ window.addEventListener("beforeunload", () => {
690
+ this.flush().finally(() => {
691
+ this.destroy();
692
+ });
693
+ });
694
+ }
695
+ }
696
+ /**
697
+ * 延迟函数
698
+ */
699
+ delay(ms) {
700
+ return new Promise((resolve) => setTimeout(resolve, ms));
701
+ }
702
+ /**
703
+ * 生成唯一ID
704
+ */
705
+ generateId() {
706
+ return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
707
+ }
708
+ /**
709
+ * 销毁资源
710
+ */
711
+ async destroy() {
712
+ if (this.flushTimer) {
713
+ clearInterval(this.flushTimer);
714
+ this.flushTimer = null;
715
+ }
716
+ if (this.logQueue.length > 0) {
717
+ await this.flush();
718
+ }
719
+ }
720
+ /**
721
+ * 获取队列大小
722
+ */
723
+ getQueueSize() {
724
+ return this.logQueue.length;
725
+ }
726
+ /**
727
+ * 更新配置
728
+ */
729
+ updateConfig(newConfig) {
730
+ this.config = {
731
+ ...this.config,
732
+ ...newConfig
733
+ };
734
+ this.startFlushTimer();
735
+ }
736
+ };
737
+ var defaultBatchLogger = null;
738
+ function batchLogInfo(level, message, source) {
739
+ if (!defaultBatchLogger) {
740
+ return;
741
+ }
742
+ defaultBatchLogger.batchLog(level, message, source);
743
+ }
744
+ __name(batchLogInfo, "batchLogInfo");
745
+ if (process.env.NODE_ENV !== "production" && typeof window !== "undefined") {
746
+ defaultBatchLogger = new BatchLogger(console);
747
+ }
748
+
749
+ // src/utils/utils.ts
750
+ var import_clsx = require("clsx");
751
+ var import_tailwind_merge = require("tailwind-merge");
752
+ function clsxWithTw(...inputs) {
753
+ return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
754
+ }
755
+ __name(clsxWithTw, "clsxWithTw");
756
+ function isPreview() {
757
+ return window.IS_MIAODA_PREVIEW;
758
+ }
759
+ __name(isPreview, "isPreview");
760
+ function normalizeBasePath(basePath) {
761
+ if (!basePath || basePath === "/") {
762
+ return "";
763
+ }
764
+ return basePath.replace(/\/+$/, "");
765
+ }
766
+ __name(normalizeBasePath, "normalizeBasePath");
767
+ function getWsPath() {
768
+ const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
769
+ const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
770
+ const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
771
+ return `${basePathWithoutTrailingSlash}/ws`;
772
+ }
773
+ __name(getWsPath, "getWsPath");
774
+ function isSparkRuntime() {
775
+ return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
776
+ }
777
+ __name(isSparkRuntime, "isSparkRuntime");
778
+
779
+ // src/components/AppContainer/utils/childApi.ts
780
+ async function getRoutes() {
781
+ let routes = [
782
+ {
783
+ path: "/"
784
+ }
785
+ ];
786
+ try {
787
+ const basePath = normalizeBasePath(process.env.CLIENT_BASE_PATH);
788
+ const res = await fetch(`${basePath}/routes.json`);
789
+ routes = await res.json();
790
+ } catch (error) {
791
+ console.warn("get routes.json error", error);
792
+ }
793
+ return routes;
794
+ }
795
+ __name(getRoutes, "getRoutes");
796
+ var childApi = {
797
+ getRoutes,
798
+ updateAppInfo: /* @__PURE__ */ __name((appInfo) => {
799
+ dispatchEvent(new CustomEvent("MiaoDaMetaInfoChanged", {
800
+ detail: appInfo
801
+ }));
802
+ }, "updateAppInfo")
803
+ };
804
+
805
+ // src/runtime/iframe-bridge.ts
806
+ async function connectParent() {
807
+ submitPostMessage({
808
+ type: "PreviewReady",
809
+ data: {}
810
+ });
811
+ batchLogInfo("info", JSON.stringify({
812
+ type: "PreviewReady",
813
+ timestamp: Date.now(),
814
+ url: window.location.href
815
+ }));
816
+ const parentOrigin = resolveParentOrigin();
817
+ if (!parentOrigin) return;
818
+ const connection = (0, import_penpal.connectToParent)({
819
+ parentOrigin,
820
+ methods: {
821
+ ...childApi
822
+ }
823
+ });
824
+ await connection.promise;
825
+ }
826
+ __name(connectParent, "connectParent");
827
+ function initIframeBridge() {
828
+ if (window.parent === window) return;
829
+ connectParent();
830
+ }
831
+ __name(initIframeBridge, "initIframeBridge");
832
+
151
833
  // src/runtime/index.ts
152
834
  if (!window.__FULLSTACK_RUNTIME_INITIALIZED__) {
153
835
  window.__FULLSTACK_RUNTIME_INITIALIZED__ = true;
154
836
  initAxiosConfig();
837
+ if (process.env.NODE_ENV !== "production") {
838
+ initIframeBridge();
839
+ }
155
840
  }
156
841
 
157
842
  // src/components/AppContainer/safety.tsx
@@ -226,36 +911,6 @@ function getInitialInfo(refresh = false) {
226
911
  }
227
912
  __name(getInitialInfo, "getInitialInfo");
228
913
 
229
- // src/utils/utils.ts
230
- var import_clsx = require("clsx");
231
- var import_tailwind_merge = require("tailwind-merge");
232
- function clsxWithTw(...inputs) {
233
- return (0, import_tailwind_merge.twMerge)((0, import_clsx.clsx)(inputs));
234
- }
235
- __name(clsxWithTw, "clsxWithTw");
236
- function isPreview() {
237
- return window.IS_MIAODA_PREVIEW;
238
- }
239
- __name(isPreview, "isPreview");
240
- function normalizeBasePath(basePath) {
241
- if (!basePath || basePath === "/") {
242
- return "";
243
- }
244
- return basePath.replace(/\/+$/, "");
245
- }
246
- __name(normalizeBasePath, "normalizeBasePath");
247
- function getWsPath() {
248
- const rawBasePath = process.env.CLIENT_BASE_PATH || "/";
249
- const normalizedBasePath = rawBasePath.startsWith("/") ? rawBasePath : `/${rawBasePath}`;
250
- const basePathWithoutTrailingSlash = normalizedBasePath.endsWith("/") ? normalizedBasePath.slice(0, -1) : normalizedBasePath;
251
- return `${basePathWithoutTrailingSlash}/ws`;
252
- }
253
- __name(getWsPath, "getWsPath");
254
- function isSparkRuntime() {
255
- return window._IS_Spark_RUNTIME ?? process.env.runtimeMode === "fullstack";
256
- }
257
- __name(isSparkRuntime, "isSparkRuntime");
258
-
259
914
  // src/integrations/getAppInfo.ts
260
915
  async function getAppInfo(refresh = false) {
261
916
  let appInfo = typeof window !== "undefined" ? window._appInfo : void 0;
@@ -1138,6 +1793,92 @@ var QueryProvider = /* @__PURE__ */ __name(({ children, client }) => {
1138
1793
  }, "QueryProvider");
1139
1794
  var QueryProvider_default = QueryProvider;
1140
1795
 
1796
+ // src/components/AppContainer/IframeBridge.tsx
1797
+ var import_react8 = require("react");
1798
+ var import_react_router_dom = require("react-router-dom");
1799
+
1800
+ // src/hooks/useUpdatingRef.ts
1801
+ var import_react7 = require("react");
1802
+ function useUpdatingRef(value) {
1803
+ const ref = (0, import_react7.useRef)(value);
1804
+ ref.current = value;
1805
+ return ref;
1806
+ }
1807
+ __name(useUpdatingRef, "useUpdatingRef");
1808
+
1809
+ // src/components/AppContainer/IframeBridge.tsx
1810
+ var RouteMessageType = /* @__PURE__ */ (function(RouteMessageType2) {
1811
+ RouteMessageType2["RouteChange"] = "RouteChange";
1812
+ RouteMessageType2["RouteBack"] = "RouteBack";
1813
+ RouteMessageType2["RouteForward"] = "RouteForward";
1814
+ return RouteMessageType2;
1815
+ })(RouteMessageType || {});
1816
+ function isRouteMessageType(type) {
1817
+ return Object.values(RouteMessageType).includes(type);
1818
+ }
1819
+ __name(isRouteMessageType, "isRouteMessageType");
1820
+ function IframeBridge() {
1821
+ const location = (0, import_react_router_dom.useLocation)();
1822
+ const navigate = (0, import_react_router_dom.useNavigate)();
1823
+ const navigateRef = useUpdatingRef(navigate);
1824
+ const isActive = (0, import_react8.useRef)(false);
1825
+ const historyBack = (0, import_react8.useCallback)((_payload) => {
1826
+ navigateRef.current(-1);
1827
+ isActive.current = true;
1828
+ }, [
1829
+ navigateRef
1830
+ ]);
1831
+ const historyForward = (0, import_react8.useCallback)((_payload) => {
1832
+ navigateRef.current(1);
1833
+ isActive.current = true;
1834
+ }, [
1835
+ navigateRef
1836
+ ]);
1837
+ const operatorMessage = (0, import_react8.useMemo)(() => ({
1838
+ ["RouteBack"]: historyBack,
1839
+ ["RouteForward"]: historyForward,
1840
+ ["RouteChange"]: navigateRef.current
1841
+ }), [
1842
+ historyBack,
1843
+ historyForward,
1844
+ navigateRef
1845
+ ]);
1846
+ (0, import_react8.useEffect)(() => {
1847
+ if (isActive.current) {
1848
+ isActive.current = false;
1849
+ return;
1850
+ }
1851
+ submitPostMessage({
1852
+ type: "ChildLocationChange",
1853
+ data: location
1854
+ });
1855
+ }, [
1856
+ location
1857
+ ]);
1858
+ const handleMessage = (0, import_react8.useCallback)((event) => {
1859
+ const data = event.data ?? {};
1860
+ if (typeof data.type === "string" && isRouteMessageType(data.type)) {
1861
+ operatorMessage[data.type](data.data);
1862
+ }
1863
+ }, [
1864
+ operatorMessage
1865
+ ]);
1866
+ (0, import_react8.useEffect)(() => {
1867
+ window.addEventListener("message", handleMessage);
1868
+ return () => {
1869
+ window.removeEventListener("message", handleMessage);
1870
+ };
1871
+ }, [
1872
+ handleMessage
1873
+ ]);
1874
+ return /* @__PURE__ */ React.createElement("div", {
1875
+ style: {
1876
+ display: "none"
1877
+ }
1878
+ });
1879
+ }
1880
+ __name(IframeBridge, "IframeBridge");
1881
+
1141
1882
  // src/components/AppContainer/utils/tea.ts
1142
1883
  var import_blueimp_md5 = __toESM(require("blueimp-md5"), 1);
1143
1884
  var import_sha1 = __toESM(require("crypto-js/sha1"), 1);
@@ -1250,13 +1991,13 @@ var reportTeaEvent = /* @__PURE__ */ __name(async ({ trackKey, trackParams = {}
1250
1991
  }, "reportTeaEvent");
1251
1992
 
1252
1993
  // src/components/AppContainer/utils/observable.ts
1253
- var import_observable_web = require("@lark-apaas/observable-web");
1994
+ var import_observable_web2 = require("@lark-apaas/observable-web");
1254
1995
  var initObservable = /* @__PURE__ */ __name(() => {
1255
1996
  try {
1256
1997
  const appId = window.appId;
1257
- import_observable_web.observable.start({
1998
+ import_observable_web2.observable.start({
1258
1999
  serviceName: "app",
1259
- env: process.env.NODE_ENV === "development" ? import_observable_web.AppEnv.Dev : import_observable_web.AppEnv.Prod,
2000
+ env: process.env.NODE_ENV === "development" ? import_observable_web2.AppEnv.Dev : import_observable_web2.AppEnv.Prod,
1260
2001
  collectorUrl: isNewPathEnabled() ? {
1261
2002
  log: `/app/${appId}/__runtime__/api/v1/observability/logs/collect`,
1262
2003
  trace: `/app/${appId}/__runtime__/api/v1/observability/traces/collect`,
@@ -1283,10 +2024,10 @@ var TrackKey = /* @__PURE__ */ (function(TrackKey2) {
1283
2024
  // src/components/AppContainer/index.tsx
1284
2025
  var AppContainer = /* @__PURE__ */ __name(({ children }) => {
1285
2026
  useAppInfo();
1286
- (0, import_react7.useEffect)(() => {
2027
+ (0, import_react9.useEffect)(() => {
1287
2028
  initObservable();
1288
2029
  }, []);
1289
- (0, import_react7.useEffect)(() => {
2030
+ (0, import_react9.useEffect)(() => {
1290
2031
  if (process.env.NODE_ENV === "production") {
1291
2032
  reportTeaEvent({
1292
2033
  trackKey: TrackKey.VIEW,
@@ -1298,14 +2039,14 @@ var AppContainer = /* @__PURE__ */ __name(({ children }) => {
1298
2039
  });
1299
2040
  }
1300
2041
  }, []);
1301
- return /* @__PURE__ */ import_react7.default.createElement(import_react7.default.Fragment, null, /* @__PURE__ */ import_react7.default.createElement(safety_default, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react7.default.createElement(import_miaoda_inspector.MiaodaInspector, null), /* @__PURE__ */ import_react7.default.createElement(QueryProvider_default, null, children));
2042
+ return /* @__PURE__ */ import_react9.default.createElement(import_react9.default.Fragment, null, /* @__PURE__ */ import_react9.default.createElement(safety_default, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react9.default.createElement(import_miaoda_inspector.MiaodaInspector, null), process.env.NODE_ENV !== "production" && /* @__PURE__ */ import_react9.default.createElement(IframeBridge, null), /* @__PURE__ */ import_react9.default.createElement(QueryProvider_default, null, children));
1302
2043
  }, "AppContainer");
1303
2044
  var AppContainer_default = AppContainer;
1304
2045
 
1305
2046
  // src/components/Welcome/index.tsx
1306
- var import_react8 = __toESM(require("react"), 1);
2047
+ var import_react10 = __toESM(require("react"), 1);
1307
2048
  var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1", description = "\u9875\u9762\u6682\u672A\u5F00\u53D1\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85..." }) => {
1308
- return /* @__PURE__ */ import_react8.default.createElement("div", {
2049
+ return /* @__PURE__ */ import_react10.default.createElement("div", {
1309
2050
  style: {
1310
2051
  display: "flex",
1311
2052
  flexDirection: "column",
@@ -1316,7 +2057,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1316
2057
  padding: "0 24px",
1317
2058
  textAlign: "center"
1318
2059
  }
1319
- }, /* @__PURE__ */ import_react8.default.createElement("img", {
2060
+ }, /* @__PURE__ */ import_react10.default.createElement("img", {
1320
2061
  style: {
1321
2062
  borderRadius: 6,
1322
2063
  marginBottom: 24
@@ -1325,7 +2066,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1325
2066
  height: "200",
1326
2067
  src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/welcome.svg",
1327
2068
  alt: "Welcome"
1328
- }), /* @__PURE__ */ import_react8.default.createElement("div", {
2069
+ }), /* @__PURE__ */ import_react10.default.createElement("div", {
1329
2070
  style: {
1330
2071
  fontSize: 16,
1331
2072
  fontWeight: 500,
@@ -1333,7 +2074,7 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1333
2074
  marginBottom: 4,
1334
2075
  color: "#1f2329"
1335
2076
  }
1336
- }, title), /* @__PURE__ */ import_react8.default.createElement("div", {
2077
+ }, title), /* @__PURE__ */ import_react10.default.createElement("div", {
1337
2078
  style: {
1338
2079
  fontSize: 16,
1339
2080
  lineHeight: "24px",
@@ -1345,9 +2086,9 @@ var Welcome = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1"
1345
2086
  var Welcome_default = Welcome;
1346
2087
 
1347
2088
  // src/components/PagePlaceholder/index.tsx
1348
- var import_react9 = __toESM(require("react"), 1);
2089
+ var import_react11 = __toESM(require("react"), 1);
1349
2090
  var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F00\u53D1", description = "\u9875\u9762\u6682\u672A\u5F00\u53D1\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85..." }) => {
1350
- return /* @__PURE__ */ import_react9.default.createElement("div", {
2091
+ return /* @__PURE__ */ import_react11.default.createElement("div", {
1351
2092
  style: {
1352
2093
  display: "flex",
1353
2094
  flexDirection: "column",
@@ -1358,7 +2099,7 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1358
2099
  height: "calc(100vh - 64px)",
1359
2100
  textAlign: "center"
1360
2101
  }
1361
- }, /* @__PURE__ */ import_react9.default.createElement("img", {
2102
+ }, /* @__PURE__ */ import_react11.default.createElement("img", {
1362
2103
  style: {
1363
2104
  borderRadius: "6px",
1364
2105
  marginBottom: "24px"
@@ -1367,14 +2108,14 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1367
2108
  height: "200",
1368
2109
  src: "https://lf3-static.bytednsdoc.com/obj/eden-cn/LMfspH/ljhwZthlaukjlkulzlp/miao/welcome.svg",
1369
2110
  alt: "Welcome"
1370
- }), /* @__PURE__ */ import_react9.default.createElement("div", {
2111
+ }), /* @__PURE__ */ import_react11.default.createElement("div", {
1371
2112
  style: {
1372
2113
  fontSize: "16px",
1373
2114
  fontWeight: 500,
1374
2115
  marginBottom: "4px",
1375
2116
  lineHeight: "24px"
1376
2117
  }
1377
- }, title), /* @__PURE__ */ import_react9.default.createElement("div", {
2118
+ }, title), /* @__PURE__ */ import_react11.default.createElement("div", {
1378
2119
  style: {
1379
2120
  color: "#6b7280",
1380
2121
  fontSize: "16px",
@@ -1390,12 +2131,12 @@ var PagePlaceholder = /* @__PURE__ */ __name(({ title = "\u9875\u9762\u5F85\u5F0
1390
2131
  var PagePlaceholder_default = PagePlaceholder;
1391
2132
 
1392
2133
  // src/route-components/ActiveLink.tsx
1393
- var import_react10 = __toESM(require("react"), 1);
1394
- var import_react_router_dom = require("react-router-dom");
1395
- var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick, className, style, children, ...rest }, ref) => {
1396
- const [currentHash, setCurrentHash] = (0, import_react10.useState)(() => typeof window !== "undefined" ? window.location.hash : "");
2134
+ var import_react12 = __toESM(require("react"), 1);
2135
+ var import_react_router_dom2 = require("react-router-dom");
2136
+ var ActiveLink = /* @__PURE__ */ (0, import_react12.forwardRef)(({ to, onClick, className, style, children, ...rest }, ref) => {
2137
+ const [currentHash, setCurrentHash] = (0, import_react12.useState)(() => typeof window !== "undefined" ? window.location.hash : "");
1397
2138
  const isHashRoute = typeof to === "string" && to.startsWith("#");
1398
- (0, import_react10.useEffect)(() => {
2139
+ (0, import_react12.useEffect)(() => {
1399
2140
  if (!isHashRoute) return;
1400
2141
  const handleHashChange = /* @__PURE__ */ __name(() => {
1401
2142
  setCurrentHash(window.location.hash);
@@ -1407,7 +2148,7 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1407
2148
  ]);
1408
2149
  const isActive = isHashRoute && currentHash === to;
1409
2150
  if (!isHashRoute) {
1410
- return /* @__PURE__ */ import_react10.default.createElement(import_react_router_dom.NavLink, {
2151
+ return /* @__PURE__ */ import_react12.default.createElement(import_react_router_dom2.NavLink, {
1411
2152
  ref,
1412
2153
  to,
1413
2154
  onClick,
@@ -1448,7 +2189,7 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1448
2189
  isPending: false,
1449
2190
  isTransitioning: false
1450
2191
  }) : children;
1451
- return /* @__PURE__ */ import_react10.default.createElement("a", {
2192
+ return /* @__PURE__ */ import_react12.default.createElement("a", {
1452
2193
  ref,
1453
2194
  href: to,
1454
2195
  onClick: handleHashClick,
@@ -1460,12 +2201,12 @@ var ActiveLink = /* @__PURE__ */ (0, import_react10.forwardRef)(({ to, onClick,
1460
2201
  ActiveLink.displayName = "ActiveLink";
1461
2202
 
1462
2203
  // src/route-components/NavLink.tsx
1463
- var React8 = __toESM(require("react"), 1);
1464
- var import_react_router_dom2 = require("react-router-dom");
1465
- var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, style, ...props }, ref) => {
2204
+ var React9 = __toESM(require("react"), 1);
2205
+ var import_react_router_dom3 = require("react-router-dom");
2206
+ var NavLink2 = /* @__PURE__ */ React9.forwardRef(({ to, children, className, style, ...props }, ref) => {
1466
2207
  const isHashLink = typeof to === "string" && to.startsWith("#");
1467
- const location = (0, import_react_router_dom2.useLocation)();
1468
- const navigate = (0, import_react_router_dom2.useNavigate)();
2208
+ const location = (0, import_react_router_dom3.useLocation)();
2209
+ const navigate = (0, import_react_router_dom3.useNavigate)();
1469
2210
  if (isHashLink) {
1470
2211
  const handleClick = /* @__PURE__ */ __name((e) => {
1471
2212
  e.preventDefault();
@@ -1486,7 +2227,7 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1486
2227
  const resolvedClassName = typeof className === "function" ? className(renderProps) : className;
1487
2228
  const resolvedStyle = typeof style === "function" ? style(renderProps) : style;
1488
2229
  const { caseSensitive, end, replace, state, preventScrollReset, relative, viewTransition, ...restProps } = props;
1489
- return /* @__PURE__ */ React8.createElement("a", {
2230
+ return /* @__PURE__ */ React9.createElement("a", {
1490
2231
  href: to,
1491
2232
  onClick: handleClick,
1492
2233
  ref,
@@ -1495,7 +2236,7 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1495
2236
  ...restProps
1496
2237
  }, typeof children === "function" ? children(renderProps) : children);
1497
2238
  }
1498
- return /* @__PURE__ */ React8.createElement(import_react_router_dom2.NavLink, {
2239
+ return /* @__PURE__ */ React9.createElement(import_react_router_dom3.NavLink, {
1499
2240
  to,
1500
2241
  ref,
1501
2242
  className,
@@ -1510,8 +2251,8 @@ var NavLink2 = /* @__PURE__ */ React8.forwardRef(({ to, children, className, sty
1510
2251
  NavLink2.displayName = "NavLink";
1511
2252
 
1512
2253
  // src/route-components/UniversalLink.tsx
1513
- var import_react11 = __toESM(require("react"), 1);
1514
- var import_react_router_dom3 = require("react-router-dom");
2254
+ var import_react13 = __toESM(require("react"), 1);
2255
+ var import_react_router_dom4 = require("react-router-dom");
1515
2256
  function isInternalRoute(to) {
1516
2257
  return !to.startsWith("#") && !to.startsWith("http://") && !to.startsWith("https://") && !to.startsWith("//");
1517
2258
  }
@@ -1520,15 +2261,15 @@ function isExternalLink(to) {
1520
2261
  return to.startsWith("http://") || to.startsWith("https://") || to.startsWith("//");
1521
2262
  }
1522
2263
  __name(isExternalLink, "isExternalLink");
1523
- var UniversalLink = /* @__PURE__ */ import_react11.default.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
2264
+ var UniversalLink = /* @__PURE__ */ import_react13.default.forwardRef(/* @__PURE__ */ __name(function UniversalLink2({ to, ...props }, ref) {
1524
2265
  if (isInternalRoute(to)) {
1525
- return /* @__PURE__ */ import_react11.default.createElement(import_react_router_dom3.Link, {
2266
+ return /* @__PURE__ */ import_react13.default.createElement(import_react_router_dom4.Link, {
1526
2267
  to,
1527
2268
  ref,
1528
2269
  ...props
1529
2270
  });
1530
2271
  }
1531
- return /* @__PURE__ */ import_react11.default.createElement("a", {
2272
+ return /* @__PURE__ */ import_react13.default.createElement("a", {
1532
2273
  href: to,
1533
2274
  ref,
1534
2275
  ...props,
@@ -1674,45 +2415,6 @@ function getEnvPath() {
1674
2415
  }
1675
2416
  __name(getEnvPath, "getEnvPath");
1676
2417
 
1677
- // src/utils/safeStringify.ts
1678
- function safeStringify(obj) {
1679
- const seen = /* @__PURE__ */ new Set();
1680
- try {
1681
- return JSON.stringify(obj, (_key, value) => {
1682
- if (typeof value === "object" && value !== null) {
1683
- if (seen.has(value)) {
1684
- return "[Circular]";
1685
- }
1686
- seen.add(value);
1687
- }
1688
- if (typeof value === "bigint") {
1689
- return value.toString();
1690
- }
1691
- if (value instanceof Date) {
1692
- return value.toISOString();
1693
- }
1694
- if (value instanceof Map) {
1695
- return Object.fromEntries(value);
1696
- }
1697
- if (value instanceof Set) {
1698
- return Array.from(value);
1699
- }
1700
- if (typeof value === "undefined") {
1701
- return "undefined";
1702
- }
1703
- if (typeof value === "symbol") {
1704
- return value.toString();
1705
- }
1706
- return value;
1707
- });
1708
- } catch {
1709
- return "";
1710
- } finally {
1711
- seen.clear();
1712
- }
1713
- }
1714
- __name(safeStringify, "safeStringify");
1715
-
1716
2418
  // src/utils/getAxiosForBackend.ts
1717
2419
  var import_axios2 = __toESM(require("axios"), 1);
1718
2420
  var axiosInstance;
@@ -1994,6 +2696,7 @@ var abstractArt3dRenderingCoverImg6 = "https://lf3-static.bytednsdoc.com/obj/ede
1994
2696
  isIpad,
1995
2697
  isMobile,
1996
2698
  isPreview,
2699
+ logger,
1997
2700
  normalizeBasePath,
1998
2701
  reportTeaEvent,
1999
2702
  resolveAppUrl,