@blocklet/sdk 1.17.7-beta-20251223-090654-55d57623 → 1.17.7-beta-20251225-073259-cb6ecf68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/config.d.ts CHANGED
@@ -155,7 +155,7 @@ declare const _default: {
155
155
  componentRemoved: string;
156
156
  envUpdate: string;
157
157
  };
158
- fetchBlockletJs: (type?: "js" | "json") => Promise<any>;
158
+ fetchBlockletJs: (type?: "js" | "json") => Promise<string | Record<string, any>>;
159
159
  getBlockletJs: (pageGroup?: string, pathPrefix?: string, source?: string) => string;
160
160
  getBlockletSettings: () => {
161
161
  theme: {
package/lib/config.js CHANGED
@@ -21,6 +21,7 @@ const constant_2 = require("@blocklet/constant");
21
21
  const util_1 = require("@blocklet/env/lib/util");
22
22
  const util_2 = require("@blocklet/meta/lib/util");
23
23
  const base32_1 = require("@abtnode/util/lib/base32");
24
+ const sleep_1 = __importDefault(require("@abtnode/util/lib/sleep"));
24
25
  const security_1 = require("./security");
25
26
  const version_1 = require("./version");
26
27
  const notification_1 = __importDefault(require("./service/notification"));
@@ -339,46 +340,68 @@ const blockletSettings = {
339
340
  federated: null,
340
341
  enableBlacklist: false,
341
342
  };
343
+ // Single-flight 模式:并发调用共享同一个 Promise,只请求一次
344
+ let _pendingBlockletRequest = null;
345
+ const _requestBlockletJson = async () => {
346
+ const componentDid = process.env.BLOCKLET_COMPONENT_DID;
347
+ const appUrl = `https://${(0, base32_1.encode)(env.appPid)}.${constant_1.DEFAULT_DID_DOMAIN}`;
348
+ const { mountPoint } = componentStore.find((x) => x.did === componentDid);
349
+ const url = (0, ufo_1.joinURL)(appUrl, mountPoint === '/' ? '' : mountPoint, '__blocklet__.js?type=json');
350
+ const res = await axios_1.default.get(url, {
351
+ timeout: 8000,
352
+ headers: {
353
+ 'User-Agent': `BlockletSDK/${version_1.version}`,
354
+ },
355
+ });
356
+ // 解析响应数据(原 type='json' 的解析逻辑)
357
+ let data;
358
+ try {
359
+ data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
360
+ }
361
+ catch (e) {
362
+ throw new Error('Invalid blocklet.json response');
363
+ }
364
+ if (typeof data !== 'object') {
365
+ throw new Error('Invalid blocklet.json data');
366
+ }
367
+ logger.info(`Fetch blocklet.json succeed: ${componentDid} from ${appUrl}`);
368
+ return data;
369
+ };
370
+ const _getBlockletData = () => {
371
+ if (_pendingBlockletRequest) {
372
+ return _pendingBlockletRequest;
373
+ }
374
+ _pendingBlockletRequest = (async () => {
375
+ try {
376
+ return await _requestBlockletJson();
377
+ }
378
+ finally {
379
+ _pendingBlockletRequest = null;
380
+ }
381
+ })();
382
+ return _pendingBlockletRequest;
383
+ };
342
384
  const fetchBlockletJs = async (type = 'js') => {
343
385
  const componentDid = process.env.BLOCKLET_COMPONENT_DID;
344
386
  const appUrl = `https://${(0, base32_1.encode)(env.appPid)}.${constant_1.DEFAULT_DID_DOMAIN}`;
345
387
  try {
346
- const { mountPoint } = componentStore.find((x) => x.did === componentDid);
347
- const url = (0, ufo_1.joinURL)(appUrl, mountPoint === '/' ? '' : mountPoint, `__blocklet__.js?nocache=1&t=${Date.now()}${type === 'json' ? '&type=json' : ''}`);
348
- const res = await axios_1.default.get(url, {
349
- timeout: 8000,
350
- headers: {
351
- 'User-Agent': `BlockletSDK/${version_1.version}`,
352
- },
353
- });
388
+ const data = await _getBlockletData();
354
389
  if (type === 'js') {
355
- if (typeof res.data === 'string' && res.data.startsWith('window.blocklet')) {
356
- blockletJs = res.data;
357
- logger.info(`Fetch blocklet.${type} succeed: ${componentDid} from ${appUrl}`);
358
- return res.data;
359
- }
360
- throw new Error('Invalid blocklet.js');
361
- }
362
- else {
363
- let data;
364
- try {
365
- data = typeof res.data === 'string' ? JSON.parse(res.data) : res.data;
366
- }
367
- catch (e) {
368
- throw new Error('Invalid blocklet.json response');
369
- }
370
- if (typeof data === 'object') {
371
- blockletSettings.theme = {
372
- ...DEFAULT_THEME_SETTINGS,
373
- ...(data.theme || {}),
374
- light: (0, theme_1.merge)(DEFAULT_THEME_SETTINGS.light, data.theme?.light || {}),
375
- dark: (0, theme_1.merge)(DEFAULT_THEME_SETTINGS.dark, data.theme?.dark || {}),
376
- };
377
- logger.info(`Fetch blocklet.${type} succeed: ${componentDid} from ${appUrl}`);
378
- return data;
379
- }
380
- throw new Error('Invalid blocklet.json data');
390
+ // JSON 数据生成 JS 字符串(模拟服务端 parseResponse 的格式)
391
+ const envStr = Object.entries(data)
392
+ .map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
393
+ .join(',');
394
+ const jsStr = `window.blocklet = {${envStr}};`;
395
+ blockletJs = jsStr;
396
+ return jsStr;
381
397
  }
398
+ blockletSettings.theme = {
399
+ ...DEFAULT_THEME_SETTINGS,
400
+ ...(data.theme || {}),
401
+ light: (0, theme_1.merge)(DEFAULT_THEME_SETTINGS.light, data.theme?.light || {}),
402
+ dark: (0, theme_1.merge)(DEFAULT_THEME_SETTINGS.dark, data.theme?.dark || {}),
403
+ };
404
+ return data;
382
405
  }
383
406
  catch (err) {
384
407
  logger.error(`Fetch blocklet.${type} failed: ${componentDid} from ${appUrl}`, err.message);
@@ -390,7 +413,7 @@ const fetchBlockletData = async () => {
390
413
  if (!blockletClient) {
391
414
  blockletClient = new blocklet_1.BlockletService();
392
415
  }
393
- const { blocklet } = await blockletClient.getBlocklet();
416
+ const { blocklet } = await blockletClient.getBlocklet(false, true);
394
417
  blockletSettings.federated = blocklet.settings?.federated;
395
418
  blockletSettings.enableBlacklist = blocklet.settings?.session?.enableBlacklist;
396
419
  return blocklet;
@@ -405,9 +428,11 @@ const getBlockletSettings = () => {
405
428
  };
406
429
  exports.getBlockletSettings = getBlockletSettings;
407
430
  const refreshBlockletContext = (0, throttle_1.default)(async () => {
431
+ // 避免多个组件间同时触发
432
+ await (0, sleep_1.default)(Math.floor(Math.random() * 701) + 300);
408
433
  // FIXME: @zhanghan 理论上应该将 fetchBlockletJs 改造为使用 fetchBlockletData,暂时先不改动这个逻辑,避免带来破坏性变更
409
434
  await Promise.all([fetchBlockletJs('js'), fetchBlockletJs('json'), fetchBlockletData()]);
410
- }, 3000, { trailing: true });
435
+ }, 5000, { trailing: true });
411
436
  // Page group is dynamic, so we need to create it on the fly
412
437
  const normalize = (prefix) => `/${prefix}/`.replace(/\/+/g, '/');
413
438
  const getBlockletJs = (pageGroup = '', pathPrefix = '', source = blockletJs) => {
@@ -25,7 +25,7 @@ const user_1 = require("../util/user");
25
25
  const VERSION = version_1.version; // version of notification sdk
26
26
  const isNotNullOrUndefined = (x) => ![null, undefined].includes(x);
27
27
  const fixUserAvatar = (user) => {
28
- if (user.avatar) {
28
+ if (user?.avatar) {
29
29
  user.avatar = (0, user_1.fixAvatar)(user.avatar);
30
30
  }
31
31
  return user;
@@ -232,7 +232,7 @@ const initClient = () => {
232
232
  });
233
233
  [...Object.keys(constant_1.BlockletInternalEvents), ...Object.keys(constant_1.TeamEvents)].forEach((key) => {
234
234
  const event = constant_1.BlockletInternalEvents[key] || constant_1.TeamEvents[key];
235
- componentChannel.on(event, async ({ status, response } = {}) => {
235
+ const handler = (0, debounce_1.default)(async ({ status, response } = {}) => {
236
236
  debug('componentChannel.on', { event, status, response });
237
237
  if (status === 'ok') {
238
238
  const { data, sender, time } = response;
@@ -267,7 +267,8 @@ const initClient = () => {
267
267
  emitError(response);
268
268
  console.error('Component channel error', { status, response });
269
269
  }
270
- });
270
+ }, 3000);
271
+ componentChannel.on(event, handler);
271
272
  });
272
273
  appPublicChannel.on(notification_1.NOTIFICATION_TYPES.HI, ({ status, response } = {}) => {
273
274
  debug('appPublicChannel.on', { event: notification_1.NOTIFICATION_TYPES.HI, status, response });
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.17.7-beta-20251223-090654-55d57623",
6
+ "version": "1.17.7-beta-20251225-073259-cb6ecf68",
7
7
  "description": "graphql client to read/write data on abt node",
8
8
  "homepage": "https://www.arcblock.io/docs/blocklet-sdk-nodejs",
9
9
  "main": "lib/index.js",
@@ -26,19 +26,19 @@
26
26
  "author": "linchen1987 <linchen.1987@foxmail.com> (http://github.com/linchen1987)",
27
27
  "license": "Apache-2.0",
28
28
  "dependencies": {
29
- "@abtnode/constant": "1.17.7-beta-20251223-090654-55d57623",
30
- "@abtnode/db-cache": "1.17.7-beta-20251223-090654-55d57623",
31
- "@abtnode/util": "1.17.7-beta-20251223-090654-55d57623",
29
+ "@abtnode/constant": "1.17.7-beta-20251225-073259-cb6ecf68",
30
+ "@abtnode/db-cache": "1.17.7-beta-20251225-073259-cb6ecf68",
31
+ "@abtnode/util": "1.17.7-beta-20251225-073259-cb6ecf68",
32
32
  "@arcblock/did": "^1.27.15",
33
33
  "@arcblock/did-connect-js": "^1.27.15",
34
34
  "@arcblock/did-ext": "^1.27.15",
35
35
  "@arcblock/jwt": "^1.27.15",
36
36
  "@arcblock/ws": "^1.27.15",
37
- "@blocklet/constant": "1.17.7-beta-20251223-090654-55d57623",
38
- "@blocklet/env": "1.17.7-beta-20251223-090654-55d57623",
37
+ "@blocklet/constant": "1.17.7-beta-20251225-073259-cb6ecf68",
38
+ "@blocklet/env": "1.17.7-beta-20251225-073259-cb6ecf68",
39
39
  "@blocklet/error": "^0.3.5",
40
- "@blocklet/meta": "1.17.7-beta-20251223-090654-55d57623",
41
- "@blocklet/server-js": "1.17.7-beta-20251223-090654-55d57623",
40
+ "@blocklet/meta": "1.17.7-beta-20251225-073259-cb6ecf68",
41
+ "@blocklet/server-js": "1.17.7-beta-20251225-073259-cb6ecf68",
42
42
  "@blocklet/theme": "^3.2.19",
43
43
  "@did-connect/authenticator": "^2.2.8",
44
44
  "@did-connect/handler": "^2.2.8",
@@ -82,5 +82,5 @@
82
82
  "ts-node": "^10.9.1",
83
83
  "typescript": "^5.6.3"
84
84
  },
85
- "gitHead": "00a82b6f4ef5818d6ec37d74be404031c693247c"
85
+ "gitHead": "16715912460ed534e1e023d7e968714e3990051d"
86
86
  }