react-ai-renderer 0.1.24 → 0.1.25
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 +86 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +86 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,8 @@ interface ComponentHandler extends BaseComponentHandler {
|
|
|
51
51
|
skeleton?: SkeletonConfig;
|
|
52
52
|
/** 组件的显示标签,用于在占位组件中显示 */
|
|
53
53
|
label?: string;
|
|
54
|
+
/** 流式渲染:为 true 时组件在 isComplete=false 阶段即渲染实际内容而非 loader */
|
|
55
|
+
streamable?: boolean;
|
|
54
56
|
}
|
|
55
57
|
/** 增强模式的组件配置 */
|
|
56
58
|
interface EnhancedComponentConfig {
|
|
@@ -70,6 +72,8 @@ interface EnhancedComponentConfig {
|
|
|
70
72
|
onRenderFinished?: (item: ComponentData$1, scope: any) => void;
|
|
71
73
|
/** 是否自闭合 */
|
|
72
74
|
selfClosing?: boolean;
|
|
75
|
+
/** 流式渲染:为 true 时组件在流式解析未完成阶段即渲染实际内容而非 loader */
|
|
76
|
+
streamable?: boolean;
|
|
73
77
|
}
|
|
74
78
|
/** 组件值类型:可以是组件本身,也可以是增强配置对象 */
|
|
75
79
|
type ComponentValue = React.ComponentType<any> | EnhancedComponentConfig;
|
package/dist/index.js
CHANGED
|
@@ -816,33 +816,37 @@ var MDXStreamingParser = /** @class */function () {
|
|
|
816
816
|
// 处理 JSON 值(对象或数组)
|
|
817
817
|
var startChar = input[j];
|
|
818
818
|
var startBracket = j;
|
|
819
|
-
// 使用局部变量跟踪属性值内部的括号嵌套
|
|
820
819
|
var localBracketCount = 0;
|
|
821
820
|
var localSquareBracketCount = 0;
|
|
822
821
|
var inValueQuote = false;
|
|
823
822
|
var valueQuoteChar = '';
|
|
823
|
+
var inBacktick = false;
|
|
824
|
+
var closingStack = [];
|
|
824
825
|
if (startChar === '{') {
|
|
825
826
|
localBracketCount = 1;
|
|
827
|
+
closingStack.push('}');
|
|
826
828
|
} else {
|
|
827
829
|
localSquareBracketCount = 1;
|
|
830
|
+
closingStack.push(']');
|
|
828
831
|
}
|
|
829
832
|
j++;
|
|
830
|
-
// 同时跟踪花括号和方括号的嵌套
|
|
831
833
|
while (j < input.length && (localBracketCount > 0 || localSquareBracketCount > 0)) {
|
|
832
|
-
if (input[j] === '
|
|
833
|
-
|
|
834
|
+
if (input[j] === '`' && !inValueQuote) {
|
|
835
|
+
inBacktick = !inBacktick;
|
|
836
|
+
j++;
|
|
837
|
+
} else if (inBacktick) {
|
|
838
|
+
j++;
|
|
839
|
+
} else if (input[j] === '"' || input[j] === "'") {
|
|
834
840
|
if (!inValueQuote) {
|
|
835
841
|
inValueQuote = true;
|
|
836
842
|
valueQuoteChar = input[j];
|
|
837
843
|
} else if (input[j] === valueQuoteChar) {
|
|
838
|
-
// 检查是否是转义的引号
|
|
839
844
|
var escapeCount = 0;
|
|
840
845
|
var k = j - 1;
|
|
841
846
|
while (k >= 0 && input[k] === '\\') {
|
|
842
847
|
escapeCount++;
|
|
843
848
|
k--;
|
|
844
849
|
}
|
|
845
|
-
// 如果是偶数个反斜杠,说明引号没有被转义
|
|
846
850
|
if (escapeCount % 2 === 0) {
|
|
847
851
|
inValueQuote = false;
|
|
848
852
|
}
|
|
@@ -850,15 +854,23 @@ var MDXStreamingParser = /** @class */function () {
|
|
|
850
854
|
j++;
|
|
851
855
|
} else if (input[j] === '{' && !inValueQuote) {
|
|
852
856
|
localBracketCount++;
|
|
857
|
+
closingStack.push('}');
|
|
853
858
|
j++;
|
|
854
859
|
} else if (input[j] === '}' && !inValueQuote) {
|
|
855
860
|
localBracketCount--;
|
|
861
|
+
if (closingStack.length > 0 && closingStack[closingStack.length - 1] === '}') {
|
|
862
|
+
closingStack.pop();
|
|
863
|
+
}
|
|
856
864
|
j++;
|
|
857
865
|
} else if (input[j] === '[' && !inValueQuote) {
|
|
858
866
|
localSquareBracketCount++;
|
|
867
|
+
closingStack.push(']');
|
|
859
868
|
j++;
|
|
860
869
|
} else if (input[j] === ']' && !inValueQuote) {
|
|
861
870
|
localSquareBracketCount--;
|
|
871
|
+
if (closingStack.length > 0 && closingStack[closingStack.length - 1] === ']') {
|
|
872
|
+
closingStack.pop();
|
|
873
|
+
}
|
|
862
874
|
j++;
|
|
863
875
|
} else {
|
|
864
876
|
j++;
|
|
@@ -866,31 +878,46 @@ var MDXStreamingParser = /** @class */function () {
|
|
|
866
878
|
}
|
|
867
879
|
var rawValue = input.slice(startBracket, j);
|
|
868
880
|
value = input.slice(startBracket + 1, j - 1);
|
|
881
|
+
// 流式修复:输入未结束但括号未闭合,尝试关闭不完整的表达式
|
|
882
|
+
if (j >= input.length && closingStack.length > 0) {
|
|
883
|
+
var healed = rawValue;
|
|
884
|
+
if (inBacktick) healed += '`';
|
|
885
|
+
if (inValueQuote) healed += valueQuoteChar;
|
|
886
|
+
healed += closingStack.reverse().join('');
|
|
887
|
+
// 剥离外层 JSX 表达式括号 {{ → {,用 (...) 包裹强制表达式上下文
|
|
888
|
+
var inner = healed.slice(1, -1);
|
|
889
|
+
try {
|
|
890
|
+
props[propName] = new Function('return (' + inner + ')')();
|
|
891
|
+
} catch (_a) {
|
|
892
|
+
try {
|
|
893
|
+
var jv = inner.replace(/`([^`]*)`/g, function (_, p1) {
|
|
894
|
+
return JSON.stringify(p1);
|
|
895
|
+
}).replace(/'([^'\\]*(\\.[^'\\]*)*)'/g, function (m) {
|
|
896
|
+
var s = m.slice(1, -1).replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
897
|
+
return "\"".concat(s, "\"");
|
|
898
|
+
}).replace(/([{,]\s*)([\p{L}_$][\p{L}\p{N}_$]*)\s*:/gu, '$1"$2":');
|
|
899
|
+
props[propName] = JSON.parse(jv);
|
|
900
|
+
} catch (_b) {
|
|
901
|
+
// 修复失败,不设置 prop,组件以骨架态渲染
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
i = j;
|
|
905
|
+
continue;
|
|
906
|
+
}
|
|
869
907
|
try {
|
|
870
|
-
// 直接使用 Function 构造器来评估 JavaScript 表达式
|
|
871
|
-
// 这比手动转换 JavaScript 对象字面量为 JSON 更可靠
|
|
872
908
|
props[propName] = new Function('return ' + rawValue)();
|
|
873
909
|
} catch (e) {
|
|
874
|
-
// 如果 Function 构造器失败,尝试手动转换并解析为 JSON
|
|
875
910
|
try {
|
|
876
|
-
// 将 JavaScript 对象字面量转换为有效的 JSON
|
|
877
|
-
// 1. 将单引号字符串转换为双引号字符串
|
|
878
911
|
var jsonValue = value.replace(/'([^'\\]*(\\.[^'\\]*)*)'/g, function (match) {
|
|
879
|
-
// 将单引号内容转换为双引号,并转义内部的双引号和反斜杠
|
|
880
912
|
var inner = match.slice(1, -1).replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
881
913
|
return "\"".concat(inner, "\"");
|
|
882
914
|
});
|
|
883
|
-
// 2. 为对象键名添加引号(如果还没有引号)
|
|
884
|
-
// 修复:使用 \p{L} 匹配 Unicode 字母(包括中文),使用 u 标志
|
|
885
915
|
jsonValue = jsonValue.replace(/([{,]\s*)([\p{L}_$][\p{L}\p{N}_$]*)\s*:/gu, '$1"$2":');
|
|
886
|
-
// 3. 处理属性值中的模板字符串
|
|
887
916
|
jsonValue = jsonValue.replace(/`([^`]*)`/g, function (match, p1) {
|
|
888
917
|
return JSON.stringify(p1);
|
|
889
918
|
});
|
|
890
|
-
// 4. 尝试解析为 JSON
|
|
891
919
|
props[propName] = JSON.parse(jsonValue);
|
|
892
920
|
} catch (jsonError) {
|
|
893
|
-
// 如果都失败了,保持原值
|
|
894
921
|
props[propName] = value;
|
|
895
922
|
}
|
|
896
923
|
}
|
|
@@ -59487,7 +59514,8 @@ function convertComponentsToHandlers(components, componentHandlers) {
|
|
|
59487
59514
|
onRenderProcess: config.onRenderProcess,
|
|
59488
59515
|
onRenderFinished: config.onRenderFinished,
|
|
59489
59516
|
loader: config.loader,
|
|
59490
|
-
label: config.label
|
|
59517
|
+
label: config.label,
|
|
59518
|
+
streamable: config.streamable
|
|
59491
59519
|
});
|
|
59492
59520
|
} else {
|
|
59493
59521
|
handlers.push({
|
|
@@ -59562,11 +59590,12 @@ function parsedStructureSignature(parsedData) {
|
|
|
59562
59590
|
}
|
|
59563
59591
|
function hasPendingLoaderComponents(parsedData, handlers) {
|
|
59564
59592
|
return parsedData.some(function (item) {
|
|
59565
|
-
var _a;
|
|
59566
59593
|
if (item.type !== 'component' || item.isComplete === true) return false;
|
|
59567
|
-
|
|
59594
|
+
var handler = handlers.find(function (h) {
|
|
59568
59595
|
return h.name === item.value;
|
|
59569
|
-
})
|
|
59596
|
+
});
|
|
59597
|
+
if (handler === null || handler === void 0 ? void 0 : handler.streamable) return false;
|
|
59598
|
+
return Boolean(handler === null || handler === void 0 ? void 0 : handler.loader);
|
|
59570
59599
|
});
|
|
59571
59600
|
}
|
|
59572
59601
|
function ReactAIRenderer(_a) {
|
|
@@ -59702,7 +59731,7 @@ function ReactAIRenderer(_a) {
|
|
|
59702
59731
|
finalComponent = [];
|
|
59703
59732
|
fallbackComponent = [];
|
|
59704
59733
|
_loop_3 = function (i) {
|
|
59705
|
-
var item, currentParsedItem, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName, cacheKey;
|
|
59734
|
+
var item, currentParsedItem, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName, cacheKey, cacheKey;
|
|
59706
59735
|
return __generator(this, function (_d) {
|
|
59707
59736
|
switch (_d.label) {
|
|
59708
59737
|
case 0:
|
|
@@ -59715,10 +59744,10 @@ function ReactAIRenderer(_a) {
|
|
|
59715
59744
|
case 1:
|
|
59716
59745
|
_result = _d.sent();
|
|
59717
59746
|
finalComponent.push(_result);
|
|
59718
|
-
return [3 /*break*/,
|
|
59747
|
+
return [3 /*break*/, 14];
|
|
59719
59748
|
case 2:
|
|
59720
59749
|
componentNameMatch = item.value.match(/<([A-Z][A-Za-z0-9]*)/);
|
|
59721
|
-
if (!componentNameMatch) return [3 /*break*/,
|
|
59750
|
+
if (!componentNameMatch) return [3 /*break*/, 12];
|
|
59722
59751
|
componentName_1 = componentNameMatch[1];
|
|
59723
59752
|
componentHandler = allComponentHandlers.find(function (c) {
|
|
59724
59753
|
return c.name === componentName_1;
|
|
@@ -59732,14 +59761,21 @@ function ReactAIRenderer(_a) {
|
|
|
59732
59761
|
loader: componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader,
|
|
59733
59762
|
key: "fallback-loader-".concat(componentName_1)
|
|
59734
59763
|
});
|
|
59735
|
-
if (!(currentParsedItem.isComplete === true || !(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader))) return [3 /*break*/,
|
|
59764
|
+
if (!(currentParsedItem.isComplete === true || !(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader))) return [3 /*break*/, 7];
|
|
59736
59765
|
cacheKey = "mdx-component-".concat(componentName_1, "-").concat(i);
|
|
59737
59766
|
if (!completedComponentsCacheRef.current.has(cacheKey)) return [3 /*break*/, 3];
|
|
59738
59767
|
_result = completedComponentsCacheRef.current.get(cacheKey);
|
|
59739
|
-
return [3 /*break*/,
|
|
59768
|
+
return [3 /*break*/, 6];
|
|
59740
59769
|
case 3:
|
|
59741
|
-
return [
|
|
59770
|
+
if (!(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.streamable)) return [3 /*break*/, 4];
|
|
59771
|
+
_result = /*#__PURE__*/React__default.createElement(componentHandler.component, __assign(__assign({}, currentParsedItem.props), {
|
|
59772
|
+
key: cacheKey
|
|
59773
|
+
}));
|
|
59774
|
+
completedComponentsCacheRef.current.set(cacheKey, _result);
|
|
59775
|
+
return [3 /*break*/, 6];
|
|
59742
59776
|
case 4:
|
|
59777
|
+
return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
|
|
59778
|
+
case 5:
|
|
59743
59779
|
_result = _d.sent();
|
|
59744
59780
|
if (/*#__PURE__*/React__default.isValidElement(_result)) {
|
|
59745
59781
|
_result = /*#__PURE__*/React__default.cloneElement(_result, {
|
|
@@ -59751,29 +59787,37 @@ function ReactAIRenderer(_a) {
|
|
|
59751
59787
|
}, _result);
|
|
59752
59788
|
}
|
|
59753
59789
|
completedComponentsCacheRef.current.set(cacheKey, _result);
|
|
59754
|
-
_d.label =
|
|
59755
|
-
case 5:
|
|
59756
|
-
finalComponent.push(_result);
|
|
59757
|
-
return [3 /*break*/, 9];
|
|
59790
|
+
_d.label = 6;
|
|
59758
59791
|
case 6:
|
|
59759
|
-
|
|
59760
|
-
|
|
59761
|
-
return [3 /*break*/, 9];
|
|
59792
|
+
finalComponent.push(_result);
|
|
59793
|
+
return [3 /*break*/, 11];
|
|
59762
59794
|
case 7:
|
|
59763
|
-
return [
|
|
59764
|
-
|
|
59765
|
-
_result =
|
|
59795
|
+
if (!(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.streamable)) return [3 /*break*/, 8];
|
|
59796
|
+
cacheKey = "mdx-component-".concat(componentName_1, "-").concat(i);
|
|
59797
|
+
_result = /*#__PURE__*/React__default.createElement(componentHandler.component, __assign(__assign({}, currentParsedItem.props), {
|
|
59798
|
+
key: cacheKey
|
|
59799
|
+
}));
|
|
59766
59800
|
finalComponent.push(_result);
|
|
59767
|
-
|
|
59801
|
+
return [3 /*break*/, 11];
|
|
59802
|
+
case 8:
|
|
59803
|
+
if (!placeholderForFallback) return [3 /*break*/, 9];
|
|
59804
|
+
finalComponent.push(placeholderForFallback);
|
|
59805
|
+
return [3 /*break*/, 11];
|
|
59768
59806
|
case 9:
|
|
59769
|
-
return [3 /*break*/, 12];
|
|
59770
|
-
case 10:
|
|
59771
59807
|
return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
|
|
59772
|
-
case
|
|
59808
|
+
case 10:
|
|
59773
59809
|
_result = _d.sent();
|
|
59774
59810
|
finalComponent.push(_result);
|
|
59775
|
-
_d.label =
|
|
59811
|
+
_d.label = 11;
|
|
59812
|
+
case 11:
|
|
59813
|
+
return [3 /*break*/, 14];
|
|
59776
59814
|
case 12:
|
|
59815
|
+
return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
|
|
59816
|
+
case 13:
|
|
59817
|
+
_result = _d.sent();
|
|
59818
|
+
finalComponent.push(_result);
|
|
59819
|
+
_d.label = 14;
|
|
59820
|
+
case 14:
|
|
59777
59821
|
fallbackComponent.length = 0;
|
|
59778
59822
|
fallbackComponent.push.apply(fallbackComponent, __spreadArray([], __read(finalComponent.slice(0, i)), false));
|
|
59779
59823
|
if (placeholderForFallback) {
|