@blocklet/launcher-workflow 2.4.3 → 2.4.5

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.
Files changed (39) hide show
  1. package/es/components/in-progress-session.js +1 -1
  2. package/es/components/launch-serverless/allocate.js +181 -0
  3. package/es/components/launch-serverless/install.js +203 -0
  4. package/es/components/launch-serverless/shared/base-serverless-layout.js +53 -0
  5. package/es/components/launch-serverless/shared/common-components.js +605 -0
  6. package/es/components/launch-serverless/shared/loading-display-layout.js +122 -0
  7. package/es/components/launch-serverless/shared/retry-error-message.js +45 -0
  8. package/es/components/launch-serverless/start-app.js +356 -0
  9. package/es/contexts/request.js +2 -2
  10. package/es/hooks/use-serial-polling.js +43 -0
  11. package/es/install.js +28 -0
  12. package/es/launch.js +1 -1
  13. package/es/locales/en.js +71 -14
  14. package/es/locales/zh.js +68 -12
  15. package/es/paid.js +1 -1
  16. package/es/prepare.js +1 -1
  17. package/es/start-app.js +28 -0
  18. package/es/util.js +181 -2
  19. package/lib/components/in-progress-session.js +3 -3
  20. package/lib/components/launch-serverless/allocate.js +198 -0
  21. package/lib/components/launch-serverless/install.js +223 -0
  22. package/lib/components/launch-serverless/shared/base-serverless-layout.js +59 -0
  23. package/lib/components/launch-serverless/shared/common-components.js +635 -0
  24. package/lib/components/launch-serverless/shared/loading-display-layout.js +131 -0
  25. package/lib/components/launch-serverless/shared/retry-error-message.js +52 -0
  26. package/lib/components/launch-serverless/start-app.js +369 -0
  27. package/lib/contexts/request.js +2 -2
  28. package/lib/hooks/use-serial-polling.js +49 -0
  29. package/lib/install.js +35 -0
  30. package/lib/launch.js +2 -2
  31. package/lib/locales/en.js +71 -14
  32. package/lib/locales/zh.js +68 -12
  33. package/lib/paid.js +2 -2
  34. package/lib/prepare.js +2 -2
  35. package/lib/start-app.js +35 -0
  36. package/lib/util.js +214 -11
  37. package/package.json +15 -12
  38. package/es/components/launch-serverless.js +0 -115
  39. package/lib/components/launch-serverless.js +0 -89
package/lib/locales/en.js CHANGED
@@ -45,15 +45,15 @@ var _default = exports.default = {
45
45
  },
46
46
  prepare: {
47
47
  serverless: {
48
- preparing: 'Allocating space on the server. Please wait...',
49
- prepared: 'The space is ready. Redirecting to the server to continue the installation...',
50
- prepareFailed: 'Failed to allocate space!'
48
+ preparing: 'Setting up your space...',
49
+ prepared: 'Space is ready! Installing your blocklet...',
50
+ prepareFailed: 'Failed to set up your space!'
51
51
  }
52
52
  },
53
53
  launch: {
54
54
  pageTitle: 'Preparing Space',
55
55
  invalidFftId: 'Invalid Purchase NFT ID',
56
- launchApp: 'Launch App',
56
+ launchApp: 'Launch Blocklet',
57
57
  launching: 'Your Blocklet Space is being baked, please be patient, it usually takes about 5 minutes',
58
58
  launched: 'Your Blocklet Space is up and running',
59
59
  launchSuccess: 'Blocklet Space is successfully launched',
@@ -61,11 +61,11 @@ var _default = exports.default = {
61
61
  waitingForLaunching: 'Your Blocklet Space launch request is being processed, please be patient, it usually takes about 5 minutes',
62
62
  accessServer: 'Access Blocklet Space',
63
63
  waiting: {
64
- starting: 'Starting Blocklet Space',
65
- securing: 'Securing Network',
66
- prepare: 'Prepare Storage',
67
- waiting: 'Waiting for Ready',
68
- done: 'Blocklet Space is Ready'
64
+ starting: 'Starting Blocklet Space...',
65
+ securing: 'Securing Network...',
66
+ prepare: 'Prepare Storage...',
67
+ waiting: 'Waiting for Ready...',
68
+ done: 'Blocklet Space is Ready...'
69
69
  },
70
70
  dialog: {
71
71
  title: 'Launch Blocklet Space',
@@ -80,6 +80,63 @@ var _default = exports.default = {
80
80
  notFoundDescription: 'You can launch the Space by clicking the button below'
81
81
  }
82
82
  },
83
+ install: {
84
+ pageTitle: 'Install Blocklet',
85
+ waiting: {
86
+ verifying: 'Verifying blocklet metadata...',
87
+ downloading: 'Downloading blocklet...',
88
+ extracting: 'Extracting blocklet data...',
89
+ downloadingComponent: 'Downloading {name}',
90
+ extractingComponent: 'Extracting {name}',
91
+ installing: 'Installing blocklet components...',
92
+ installed: 'Blocklet is installed'
93
+ },
94
+ installing: 'Installing Blocklet...',
95
+ installed: 'Blocklet is installed',
96
+ installFailed: 'Install Blocklet Failed!'
97
+ },
98
+ startApp: {
99
+ pageTitle: 'Start Blocklet',
100
+ starting: 'Starting Blocklet...',
101
+ started: 'Blocklet is ready to use!',
102
+ startedDescription: 'Your blocklet has been successfully started and is now ready to use.',
103
+ startFailed: 'Start Blocklet Failed',
104
+ installFailed: 'Install Blocklet Failed',
105
+ visit: 'Visit Blocklet',
106
+ dashboard: 'View Blocklet Dashboard',
107
+ subscription: 'Manage Subscription',
108
+ unknownApp: 'Unknown Blocklet',
109
+ appInfo: 'Blocklet Information',
110
+ appDid: 'Blocklet DID',
111
+ serverUrl: 'Server URL',
112
+ status: 'Status',
113
+ version: 'Version',
114
+ running: 'Running',
115
+ myOrders: 'My Orders',
116
+ myOrdersDesc: 'View and manage all your orders',
117
+ projectName: 'Project Name',
118
+ visitUrl: 'Visit URL',
119
+ visitApp: 'Visit Blocklet',
120
+ visitAppDesc: 'Open your blocklet homepage',
121
+ dashboardDesc: 'View monitoring status and resource usage',
122
+ subscriptionDesc: 'Manage stake amount and renewal settings',
123
+ appManagement: 'Blocklet Management',
124
+ appManagementDesc: 'Change configuration and blocklet settings',
125
+ waiting: {
126
+ starting: 'Starting blocklet...',
127
+ parsing: 'Parsing blocklet metadata...',
128
+ initializing: 'Initializing blocklet configuration...',
129
+ initializingOwner: 'Initializing blocklet owner...',
130
+ creatingSecurityRules: 'Creating default security rules...',
131
+ assigningDomain: 'Assigning default domain name...',
132
+ waitingForDomain: 'Waiting for default domain name...'
133
+ }
134
+ },
135
+ loading: {
136
+ completed: 'completed',
137
+ retry: 'Retry',
138
+ remainingTime: 'About {time} remaining'
139
+ },
83
140
  start: {
84
141
  title: 'Starting Space',
85
142
  error: {
@@ -114,10 +171,10 @@ var _default = exports.default = {
114
171
  morePlanPrompt: 'Flip the page to see more plans',
115
172
  redeem: 'Select purchased space',
116
173
  noProducts: 'No products available for purchase, please check your payment-kit config',
117
- serverlessNotSupported: 'This app is not allowed in sigular and on-demand space, please select dedicated space',
174
+ serverlessNotSupported: 'This blocklet is not allowed in sigular and on-demand space, please select dedicated space',
118
175
  componentCount: '{count} Component Included',
119
176
  componentsCount: '{count} Components Included',
120
- onDemandNotSupport: 'This app does not support installation in on-demand space, please purchase dedicated space or install in your own dedicated space',
177
+ onDemandNotSupport: 'This blocklet does not support installation in on-demand space, please purchase dedicated space or install in your own dedicated space',
121
178
  dialog: {
122
179
  title: 'Purchase Blocklet Space NFT',
123
180
  scan: 'Scan the QR code below with your DID wallet to complete purchase',
@@ -126,7 +183,7 @@ var _default = exports.default = {
126
183
  },
127
184
  serverlessDialog: {
128
185
  title: 'Purchase successfully',
129
- redirectToStoreButton: 'Go to install the application →',
186
+ redirectToStoreButton: 'Go to install the blocklet →',
130
187
  purchaseServerlessSuccess: 'The purchase of Running Space is successful and you can go ahead and install Blocklet.'
131
188
  },
132
189
  inProgress: {
@@ -147,7 +204,7 @@ var _default = exports.default = {
147
204
  paid: 'Current order has been paid',
148
205
  paidDescription: 'The current order has been paid, you can choose to purchase a new space or continue the launch process.',
149
206
  installed: 'Order has been installed',
150
- installedDescription: 'The current order has been successfully installed, you can choose to purchase a new space or jump to the current application.',
207
+ installedDescription: 'The current order has been successfully installed, you can choose to purchase a new space or jump to the current blocklet.',
151
208
  expired: 'Order has been expired',
152
209
  expiredDescription: 'The current order has expired, you can choose to purchase a new space.'
153
210
  }
@@ -162,7 +219,7 @@ var _default = exports.default = {
162
219
  agreement: '{name} User Agreement',
163
220
  estimatedCost: 'Estimated Cost',
164
221
  estimatedCostFreeTrial: 'Estimated Cost After The Trial ends',
165
- estimatedCostHint: 'The total cost will vary depending on the actual number and duration of components used in the application. The calculation method is: Unit price of component * Number of components * Duration.',
222
+ estimatedCostHint: 'The total cost will vary depending on the actual number and duration of components used in the blocklet. The calculation method is: Unit price of component * Number of components * Duration.',
166
223
  freeTrial: 'Free Trial',
167
224
  freeTrialHint: 'Free trial for {duration}',
168
225
  stakeAmount: 'Stake Amount',
package/lib/locales/zh.js CHANGED
@@ -53,7 +53,7 @@ var _default = exports.default = {
53
53
  launch: {
54
54
  pageTitle: '准备空间',
55
55
  invalidFftId: '无效的购买凭证',
56
- launchApp: '启动应用',
56
+ launchApp: '启动 Blocklet',
57
57
  launching: '空间正在启动中, 大约需要 5 分钟',
58
58
  launched: '空间已启动',
59
59
  launchSuccess: '创建空间成功',
@@ -61,11 +61,11 @@ var _default = exports.default = {
61
61
  waitingForLaunching: '空间正在启动中,大约需要 5 分钟',
62
62
  accessServer: '访问空间',
63
63
  waiting: {
64
- starting: '启动空间',
65
- securing: '确保空间的网络安全',
66
- prepare: '准备好空间存储',
67
- waiting: '等待空间就绪',
68
- done: '空间已准备就绪'
64
+ starting: '启动空间...',
65
+ securing: '确保空间的网络安全...',
66
+ prepare: '准备好空间存储...',
67
+ waiting: '等待空间就绪...',
68
+ done: '空间已准备就绪...'
69
69
  },
70
70
  dialog: {
71
71
  title: '创建空间',
@@ -80,6 +80,62 @@ var _default = exports.default = {
80
80
  notFoundDescription: '您可以点击下面按钮启动空间'
81
81
  }
82
82
  },
83
+ install: {
84
+ pageTitle: '安装 Blocklet',
85
+ waiting: {
86
+ verifying: '验证 Blocklet 元数据...',
87
+ downloading: '下载 Blocklet...',
88
+ extracting: '提取 Blocklet 数据...',
89
+ downloadingComponent: '下载 {name}',
90
+ extractingComponent: '提取 {name}',
91
+ installing: '安装 Blocklet 组件...',
92
+ installed: 'Blocklet 已安装'
93
+ },
94
+ installing: '正在安装 Blocklet...',
95
+ installFailed: '安装 Blocklet 失败!'
96
+ },
97
+ startApp: {
98
+ pageTitle: '启动 Blocklet',
99
+ starting: '正在启动 Blocklet...',
100
+ started: 'Blocklet 启动成功',
101
+ startedDescription: '您的 Blocklet 已成功启动并准备就绪,现在可以开始使用了。',
102
+ startFailed: '启动 Blocklet 失败',
103
+ installFailed: '安装 Blocklet 失败',
104
+ visit: '访问 Blocklet',
105
+ dashboard: '查看 Blocklet 仪表盘',
106
+ subscription: '管理订阅',
107
+ unknownApp: '未知 Blocklet',
108
+ appInfo: 'Blocklet 信息',
109
+ appDid: 'Blocklet DID',
110
+ serverUrl: '服务器地址',
111
+ status: '状态',
112
+ version: '版本',
113
+ running: '运行中',
114
+ myOrders: '我的订单',
115
+ myOrdersDesc: '查看和管理您的所有订单',
116
+ projectName: '项目名称',
117
+ visitUrl: '访问地址',
118
+ visitApp: '访问 Blocklet',
119
+ visitAppDesc: '打开您的 Blocklet 主页面',
120
+ dashboardDesc: '查看监控状态和资源使用',
121
+ subscriptionDesc: '管理质押金额和续费设置',
122
+ appManagement: 'Blocklet 管理',
123
+ appManagementDesc: '更改配置和 Blocklet 设置',
124
+ waiting: {
125
+ starting: '正在启动 Blocklet...',
126
+ parsing: '正在解析 Blocklet 元数据...',
127
+ initializing: '正在初始化 Blocklet 配置...',
128
+ initializingOwner: '正在初始化 Blocklet 所有者...',
129
+ creatingSecurityRules: '正在创建默认安全规则...',
130
+ assigningDomain: '正在为 Blocklet 分配默认域名...',
131
+ waitingForDomain: '正在等待默认域名生效...'
132
+ }
133
+ },
134
+ loading: {
135
+ completed: '完成',
136
+ retry: '重试',
137
+ remainingTime: '大约需要 {time}'
138
+ },
83
139
  start: {
84
140
  title: '启动空间',
85
141
  error: {
@@ -114,10 +170,10 @@ var _default = exports.default = {
114
170
  noPlan: '选择套餐以继续',
115
171
  hasPlan: '选用{name}',
116
172
  noProducts: '没有可购买的商品,请检查 PaymentKit 的配置',
117
- serverlessNotSupported: '该应用被禁止能在单应用或者按需空间中运行,请选择专用空间',
173
+ serverlessNotSupported: '该 Blocklet 被禁止能在单 Blocklet 或者按需空间中运行,请选择专用空间',
118
174
  componentCount: '共 {count} 个组件',
119
175
  componentsCount: '共 {count} 个组件',
120
- onDemandNotSupport: '该应用不支持安装在按需空间中,请购买专用空间,或者安装在自己已有的专用空间中',
176
+ onDemandNotSupport: '该 Blocklet 不支持安装在按需空间中,请购买专用空间,或者安装在自己已有的专用空间中',
121
177
  dialog: {
122
178
  title: '购买 Blocklet Server NFT',
123
179
  scan: '用您的 DID 钱包扫描下面的二维码完成购买',
@@ -126,8 +182,8 @@ var _default = exports.default = {
126
182
  },
127
183
  serverlessDialog: {
128
184
  title: '购买成功',
129
- redirectToStoreButton: '去安装应用 →',
130
- purchaseServerlessSuccess: '购买运行空间成功,您可以去安装应用.'
185
+ redirectToStoreButton: '去安装 Blocklet →',
186
+ purchaseServerlessSuccess: '购买运行空间成功,您可以去安装 Blocklet.'
131
187
  },
132
188
  inProgress: {
133
189
  title: '未完成的订单',
@@ -147,7 +203,7 @@ var _default = exports.default = {
147
203
  paid: '订单已支付',
148
204
  paidDescription: '检测当前订单已经支付,您可以选择购买新的空间,或者继续启动流程',
149
205
  installed: '订单已安装',
150
- installedDescription: '检测当前订单已经安装成功,您可以选择购买新的空间,或者跳转到当前应用。',
206
+ installedDescription: '检测当前订单已经安装成功,您可以选择购买新的空间,或者跳转到当前 Blocklet。',
151
207
  expired: '订单已过期',
152
208
  expiredDescription: '检测当前订单已经过期,您可以选择购买新的空间。'
153
209
  }
@@ -162,7 +218,7 @@ var _default = exports.default = {
162
218
  agreement: '{name} 用户协议',
163
219
  estimatedCostFreeTrial: '试用结束后估算成本',
164
220
  estimatedCost: '估算成本',
165
- estimatedCostHint: '总成本会根据应用实际使用的组件数量和时长而变化,计算方式为: 组件单价*组件数量*时长',
221
+ estimatedCostHint: '总成本会根据 Blocklet 实际使用的组件数量和时长而变化,计算方式为: 组件单价*组件数量*时长',
166
222
  freeTrial: '免费试用',
167
223
  freeTrialHint: '免费试用{duration}',
168
224
  stakeAmount: '质押金额',
package/lib/paid.js CHANGED
@@ -10,7 +10,7 @@ var _CircularProgress = _interopRequireDefault(require("@mui/material/CircularPr
10
10
  var _ahooks = require("ahooks");
11
11
  var _react = require("react");
12
12
  var _reactRouterDom = require("react-router-dom");
13
- var _urlJoin = _interopRequireDefault(require("url-join"));
13
+ var _ufo = require("ufo");
14
14
  var _locale = require("./contexts/locale");
15
15
  var _request = _interopRequireDefault(require("./contexts/request"));
16
16
  var _workflow = require("./contexts/workflow");
@@ -48,7 +48,7 @@ function PurchaseSuccess() {
48
48
  if ((data === null || data === void 0 ? void 0 : data.status) >= _constant.LAUNCH_STATUS.nftMinted) {
49
49
  params.set('launchType', data.type);
50
50
  navigate({
51
- pathname: (0, _urlJoin.default)(routerPrefix, "/launch/".concat(data.id)),
51
+ pathname: (0, _ufo.joinURL)(routerPrefix, "/launch/".concat(data.id)),
52
52
  search: params.toString()
53
53
  });
54
54
  }
package/lib/prepare.js CHANGED
@@ -23,7 +23,7 @@ var _react = require("react");
23
23
  var _reactRouterDom = require("react-router-dom");
24
24
  var _useAsync = _interopRequireDefault(require("react-use/lib/useAsync"));
25
25
  var _useSetState = _interopRequireDefault(require("react-use/lib/useSetState"));
26
- var _urlJoin = _interopRequireDefault(require("url-join"));
26
+ var _ufo = require("ufo");
27
27
  var _confirm = _interopRequireDefault(require("./components/confirm"));
28
28
  var _body = _interopRequireDefault(require("./components/layout/body"));
29
29
  var _header = _interopRequireDefault(require("./components/layout/header"));
@@ -299,7 +299,7 @@ function Content(_ref) {
299
299
  opacity: 0.8
300
300
  }
301
301
  },
302
- to: (0, _urlJoin.default)(routerPrefix, "/purchase/select".concat(window.location.search)),
302
+ to: (0, _ufo.joinURL)(routerPrefix, "/purchase/select".concat(window.location.search)),
303
303
  children: t('purchase.selectSpaceHint')
304
304
  })]
305
305
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_Box.default, {
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = Launch;
7
+ var _react = require("react");
8
+ var _reactRouterDom = require("react-router-dom");
9
+ var _startApp = _interopRequireDefault(require("./components/launch-serverless/start-app"));
10
+ var _session = require("./contexts/session");
11
+ var _jsxRuntime = require("react/jsx-runtime");
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ function Launch() {
14
+ const {
15
+ sessionId
16
+ } = (0, _reactRouterDom.useParams)();
17
+ const {
18
+ session
19
+ } = (0, _session.useSessionContext)();
20
+ (0, _react.useEffect)(() => {
21
+ if (!session.user) {
22
+ return session.login(() => {
23
+ session.refresh();
24
+ });
25
+ }
26
+ return () => {};
27
+ // eslint-disable-next-line react-hooks/exhaustive-deps
28
+ }, [session.user]);
29
+ if (!session.user) {
30
+ return '';
31
+ }
32
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_startApp.default, {
33
+ sessionId: sessionId
34
+ });
35
+ }
package/lib/util.js CHANGED
@@ -3,19 +3,31 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.getAsset = exports.getAPIResponseError = exports.BLOCKLET_STORE_URL = void 0;
6
+ exports.getAPIResponseError = exports.checkUrlAccessible = exports.checkBlockletAccessible = exports.BLOCKLET_STORE_URL = void 0;
7
+ exports.getAccessUrl = getAccessUrl;
8
+ exports.getAsset = exports.getAccessibleUrl = void 0;
7
9
  exports.getBlockletMetaUrl = getBlockletMetaUrl;
8
- exports.loadURL = exports.launchSession = exports.getPrice = exports.getLaunchBlockletUrl = void 0;
10
+ exports.getBlockletUrl = getBlockletUrl;
11
+ exports.getBlockletUrls = getBlockletUrls;
12
+ exports.loadURL = exports.launchSession = exports.isUrlAccessible = exports.getPrice = exports.getLaunchBlockletUrl = void 0;
13
+ exports.sleep = sleep;
14
+ exports.waitingForRaceAccessible = exports.sortUrls = void 0;
15
+ var _constant = require("@abtnode/constant");
16
+ var _axios = _interopRequireDefault(require("@abtnode/util/lib/axios"));
17
+ var _normalizePathPrefix = _interopRequireDefault(require("@abtnode/util/lib/normalize-path-prefix"));
18
+ var _tryWithTimeout = _interopRequireDefault(require("@abtnode/util/lib/try-with-timeout"));
19
+ var _urlEvaluation = require("@abtnode/util/lib/url-evaluation");
20
+ var _checkAccessibleBrowser = _interopRequireDefault(require("@abtnode/util/lib/url-evaluation/check-accessible-browser"));
9
21
  var _api = require("@blocklet/launcher-util/es/api");
10
22
  var _util = require("@blocklet/launcher-ux/lib/util");
11
23
  var _lodash = _interopRequireDefault(require("lodash.get"));
12
24
  var _lodash2 = _interopRequireDefault(require("lodash.noop"));
13
25
  var _lodash3 = _interopRequireDefault(require("lodash.pick"));
14
- var _urlJoin = _interopRequireDefault(require("url-join"));
26
+ var _ufo = require("ufo");
15
27
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
28
  const BLOCKLET_STORE_URL = exports.BLOCKLET_STORE_URL = (0, _lodash.default)(window, 'blocklet.LAUNCHER_BLOCKLET_STORE_URL') || 'https://store.blocklet.dev';
17
29
  function getBlockletMetaUrl(registry, did) {
18
- return (0, _urlJoin.default)(registry, "/api/blocklets/".concat(did, "/blocklet.json?source=webapp"));
30
+ return (0, _ufo.joinURL)(registry, "/api/blocklets/".concat(did, "/blocklet.json?source=webapp"));
19
31
  }
20
32
 
21
33
  // FIXME: @wangshijun just use sessionId and launcherUrl to make the whole workflow more simple
@@ -37,7 +49,7 @@ const getLaunchBlockletUrl = _ref => {
37
49
  const serverPath = from === 'did-spaces' ? '/blocklets/restore/verify-ownership' : '/launch-blocklet/install';
38
50
 
39
51
  // FIXME: @zhenqiang 这里为何要写这个 TODO?我看 server 代码里面还有不少地方有 `fromLauncher`
40
- let result = (0, _urlJoin.default)(serverUrl, serverPath, "?blocklet_meta_url=".concat(encodeURIComponent(blockletMetaUrl), "&fromLauncher=true&from=launcher&launcherUrl=").concat(encodeURIComponent(launcherUrl)));
52
+ let result = (0, _ufo.joinURL)(serverUrl, serverPath, "?blocklet_meta_url=".concat(encodeURIComponent(blockletMetaUrl), "&fromLauncher=true&from=launcher&launcherUrl=").concat(encodeURIComponent(launcherUrl)));
41
53
  if (launchType) {
42
54
  result += "&launchType=".concat(launchType);
43
55
  }
@@ -82,7 +94,7 @@ const loadURL = url => new Promise(resolve => {
82
94
  });
83
95
  exports.loadURL = loadURL;
84
96
  const getAsset = async (chainHost, address) => {
85
- const url = (0, _urlJoin.default)(new URL(chainHost).origin, '/api/gql/');
97
+ const url = (0, _ufo.joinURL)(new URL(chainHost).origin, '/api/gql/');
86
98
  const result = await (0, _api.create)().post(url, JSON.stringify({
87
99
  query: "{\n getAssetState(address: \"".concat(address, "\") {\n state {\n address\n data {\n typeUrl\n value\n }\n display {\n type\n content\n }\n issuer\n owner\n parent\n tags\n }\n }\n }")
88
100
  }), {
@@ -118,7 +130,7 @@ exports.getPrice = getPrice;
118
130
  const launchSession = exports.launchSession = {
119
131
  load: function load(api, prefix, sessionId, url) {
120
132
  let done = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _lodash2.default;
121
- api.get((0, _urlJoin.default)(prefix, "/launches/".concat(sessionId))).then(result => {
133
+ api.get((0, _ufo.joinURL)(prefix, "/launches/".concat(sessionId))).then(result => {
122
134
  done(null, result.data.launch);
123
135
  }).catch(err => {
124
136
  console.error('Failed to load launch session', err);
@@ -129,7 +141,7 @@ const launchSession = exports.launchSession = {
129
141
  var _window$blockletMeta;
130
142
  let done = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _lodash2.default;
131
143
  const from = (0, _util.getFromQuery)('from');
132
- api.post((0, _urlJoin.default)(prefix, '/launches'), {
144
+ api.post((0, _ufo.joinURL)(prefix, '/launches'), {
133
145
  blockletMetaUrl: url,
134
146
  from,
135
147
  blockletMeta: window.blockletMeta && (0, _lodash3.default)((_window$blockletMeta = window.blockletMeta) === null || _window$blockletMeta === void 0 ? void 0 : _window$blockletMeta.meta, ['did', 'name', 'title', 'description', 'version', 'logo']),
@@ -143,7 +155,7 @@ const launchSession = exports.launchSession = {
143
155
  },
144
156
  connect: function connect(api, prefix, sessionId, userDid) {
145
157
  let done = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : _lodash2.default;
146
- api.post((0, _urlJoin.default)(prefix, "/launches/".concat(sessionId, "/connect")), {
158
+ api.post((0, _ufo.joinURL)(prefix, "/launches/".concat(sessionId, "/connect")), {
147
159
  userDid
148
160
  }).then(result => {
149
161
  done(null, result.data.launch);
@@ -154,7 +166,7 @@ const launchSession = exports.launchSession = {
154
166
  },
155
167
  select: function select(api, prefix, sessionId, type, planId) {
156
168
  let done = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : _lodash2.default;
157
- api.post((0, _urlJoin.default)(prefix, "/launches/".concat(sessionId, "/select")), {
169
+ api.post((0, _ufo.joinURL)(prefix, "/launches/".concat(sessionId, "/select")), {
158
170
  type,
159
171
  planId
160
172
  }).then(result => {
@@ -164,4 +176,195 @@ const launchSession = exports.launchSession = {
164
176
  done(err);
165
177
  });
166
178
  }
167
- };
179
+ };
180
+ function sleep(t) {
181
+ // eslint-disable-next-line no-promise-executor-return
182
+ return new Promise(resolve => setTimeout(resolve, t));
183
+ }
184
+ const isUrlAccessible = url => (0, _checkAccessibleBrowser.default)((0, _ufo.joinURL)(new URL(url).origin, _constant.WELLKNOWN_PING_PREFIX));
185
+ exports.isUrlAccessible = isUrlAccessible;
186
+ const checkBlockletAccessible = exports.checkBlockletAccessible = async function checkBlockletAccessible(url) {
187
+ let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 5000;
188
+ let controller = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
189
+ try {
190
+ const urlObj = new URL(url);
191
+ urlObj.protocol = 'https';
192
+ const res = await _axios.default.get((0, _ufo.joinURL)(urlObj.toString(), '/api/__blocklet__.js?type=json'), {
193
+ timeout,
194
+ signal: controller === null || controller === void 0 ? void 0 : controller.signal,
195
+ validateStatus: status => {
196
+ return status >= 200 && status < 400 || status === 503; // 503 是 not running, 可以访问 blocklet service
197
+ }
198
+ });
199
+ return res.data;
200
+ } catch (error) {
201
+ return null;
202
+ }
203
+ };
204
+ const checkUrlAccessible = exports.checkUrlAccessible = async function checkUrlAccessible(url) {
205
+ let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 30 * 1000;
206
+ let controller = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
207
+ try {
208
+ return await (0, _tryWithTimeout.default)(async () => {
209
+ let res = null;
210
+ do {
211
+ var _controller$signal;
212
+ res = await checkBlockletAccessible(url, 5000, controller);
213
+ await sleep(2000);
214
+ } while (!res && !(controller !== null && controller !== void 0 && (_controller$signal = controller.signal) !== null && _controller$signal !== void 0 && _controller$signal.aborted));
215
+ return res;
216
+ }, timeout);
217
+ } catch (error) {
218
+ console.error(error);
219
+ return null;
220
+ }
221
+ };
222
+ const waitingForRaceAccessible = exports.waitingForRaceAccessible = async function waitingForRaceAccessible(urls) {
223
+ let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 30 * 1000;
224
+ // Create an AbortController for each request
225
+ const controllers = urls.map(() => new AbortController());
226
+ try {
227
+ const tasks = urls.map((url, index) => checkUrlAccessible(url, timeout, controllers[index]).then(res => [url, res]).catch(error => {
228
+ // If this request failed but wasn't aborted, we should still propagate the error
229
+ if (error.name !== 'AbortError') {
230
+ throw error;
231
+ }
232
+ return null;
233
+ }));
234
+
235
+ // Add a timeout promise to the race
236
+ const timeoutPromise = new Promise((_, reject) => {
237
+ setTimeout(() => reject(new Error('All requests timed out')), timeout);
238
+ });
239
+
240
+ // Race all tasks including the timeout
241
+ const result = await Promise.race([
242
+ // Wait for the first successful response
243
+ ...tasks, timeoutPromise]);
244
+
245
+ // Cancel all other requests
246
+ controllers.forEach(controller => controller.abort());
247
+ return result;
248
+ } catch (error) {
249
+ // Cancel all requests on error
250
+ controllers.forEach(controller => controller.abort());
251
+ throw error;
252
+ }
253
+ };
254
+ const waitingForAccessible = async function waitingForAccessible(urls) {
255
+ let timeout = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 30 * 1000;
256
+ const tasks = await urls.map(url => checkUrlAccessible(url, timeout));
257
+ const result = await Promise.all(tasks);
258
+ return result;
259
+ };
260
+ const sortUrls = urls => {
261
+ return (0, _urlEvaluation.evaluateURLs)(urls, {
262
+ checkAccessible: null
263
+ }).then(items => items.map(item => item.url));
264
+ };
265
+ exports.sortUrls = sortUrls;
266
+ const getAccessibleUrl = async urls => {
267
+ try {
268
+ await waitingForAccessible(urls);
269
+ const res = await (0, _urlEvaluation.evaluateURLs)(urls, {
270
+ checkAccessible: checkBlockletAccessible
271
+ });
272
+ return res[0].url;
273
+ } catch (error) {
274
+ console.warn('get accessible url failed', error);
275
+ return '';
276
+ }
277
+ };
278
+
279
+ /**
280
+ * get access url
281
+ * auto fix http/https, port, query
282
+ * docker friendly
283
+ */
284
+ exports.getAccessibleUrl = getAccessibleUrl;
285
+ function getAccessUrl(hostname) {
286
+ let path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
287
+ let params = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
288
+ if (!hostname) {
289
+ return '';
290
+ }
291
+ try {
292
+ let port = '';
293
+ const browserPort = Number(window.location.port);
294
+ if (process.env.NODE_ENV !== 'development' && browserPort && ![80, 443].includes(browserPort)) {
295
+ port = ":".concat(browserPort);
296
+ }
297
+ const urlObj = new URL("".concat(window.location.protocol, "//").concat(hostname).concat(port));
298
+ urlObj.pathname = path;
299
+ const url = urlObj.href.replace(/\/$/, '');
300
+ if (!params || !Object.keys(params)) {
301
+ return url;
302
+ }
303
+ const searchParams = new URLSearchParams();
304
+ Object.keys(params).forEach(key => {
305
+ searchParams.append(key, params[key]);
306
+ });
307
+ return "".concat(url).concat(urlObj.pathname === '/' ? '/' : '', "?").concat(searchParams.toString());
308
+ } catch (err) {
309
+ console.error(err);
310
+ return '';
311
+ }
312
+ }
313
+ function getBlockletUrl() {
314
+ let {
315
+ blocklet,
316
+ domain: inputDomain,
317
+ mountPoint: inputMountPoint,
318
+ params
319
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
320
+ const {
321
+ site
322
+ } = blocklet;
323
+ if (!site) {
324
+ return null;
325
+ }
326
+ const domain = inputDomain || (site.domainAliases || [])[0];
327
+ if (!domain) {
328
+ return null;
329
+ }
330
+ let mountPoint = inputMountPoint;
331
+ if (!mountPoint) {
332
+ const rule = site.rules.filter(x => !x.from.pathPrefix.startsWith(_constant.WELLKNOWN_PATH_PREFIX))[0];
333
+ mountPoint = rule ? rule.from.pathPrefix : '/';
334
+ }
335
+ return getAccessUrl(domain.value, mountPoint, params);
336
+ }
337
+ function getBlockletUrls() {
338
+ let {
339
+ blocklet,
340
+ mountPoint: inputMountPoint,
341
+ params
342
+ } = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
343
+ const {
344
+ site
345
+ } = blocklet;
346
+ if (!site) {
347
+ return [];
348
+ }
349
+ const domains = site.domainAliases || [];
350
+ if (!domains.length) {
351
+ return [];
352
+ }
353
+ let mountPoint = inputMountPoint;
354
+ if (!mountPoint) {
355
+ var _rule, _rule2;
356
+ const rules = site.rules.filter(x => !x.from.pathPrefix.startsWith(_constant.WELLKNOWN_PATH_PREFIX));
357
+ let rule = rules[0];
358
+ if (((_rule = rule) === null || _rule === void 0 || (_rule = _rule.from) === null || _rule === void 0 ? void 0 : _rule.pathPrefix) !== '/') {
359
+ const rootRule = rules.find(x => {
360
+ var _x$from;
361
+ return ((_x$from = x.from) === null || _x$from === void 0 ? void 0 : _x$from.pathPrefix) === '/';
362
+ });
363
+ if (rootRule) {
364
+ rule = rootRule;
365
+ }
366
+ }
367
+ mountPoint = (0, _normalizePathPrefix.default)(((_rule2 = rule) === null || _rule2 === void 0 || (_rule2 = _rule2.from) === null || _rule2 === void 0 ? void 0 : _rule2.pathPrefix) || '/');
368
+ }
369
+ return domains.map(domain => getAccessUrl(domain.value, mountPoint, params));
370
+ }