mirror of
https://github.com/WenPai-org/wpmind.git
synced 2025-08-03 02:48:41 +08:00
change our own JSON parser to untruncate-json lib, since it works fast and correctly
This commit is contained in:
parent
b2c3fbf927
commit
0ce98282ba
3 changed files with 15 additions and 149 deletions
12
package-lock.json
generated
12
package-lock.json
generated
|
@ -1,17 +1,18 @@
|
||||||
{
|
{
|
||||||
"name": "mind",
|
"name": "mind",
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "mind",
|
"name": "mind",
|
||||||
"version": "0.1.2",
|
"version": "0.2.0",
|
||||||
"license": "GPL-2.0-or-later",
|
"license": "GPL-2.0-or-later",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"marked": "^10.0.0",
|
"marked": "^10.0.0",
|
||||||
"react-transition-group": "^4.4.5"
|
"react-transition-group": "^4.4.5",
|
||||||
|
"untruncate-json": "^0.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@wordpress/eslint-plugin": "^17.2.0",
|
"@wordpress/eslint-plugin": "^17.2.0",
|
||||||
|
@ -17596,6 +17597,11 @@
|
||||||
"node": ">=8"
|
"node": ">=8"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/untruncate-json": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/untruncate-json/-/untruncate-json-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-4W9enDK4X1y1s2S/Rz7ysw6kDuMS3VmRjMFg7GZrNO+98OSe+x5Lh7PKYoVjy3lW/1wmhs6HW0lusnQRHgMarA=="
|
||||||
|
},
|
||||||
"node_modules/update-browserslist-db": {
|
"node_modules/update-browserslist-db": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"marked": "^10.0.0",
|
"marked": "^10.0.0",
|
||||||
"react-transition-group": "^4.4.5"
|
"react-transition-group": "^4.4.5",
|
||||||
|
"untruncate-json": "^0.0.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import untruncateJson from 'untruncate-json';
|
||||||
|
|
||||||
import { createBlock } from '@wordpress/blocks';
|
import { createBlock } from '@wordpress/blocks';
|
||||||
|
|
||||||
export default class BlocksStreamProcessor {
|
export default class BlocksStreamProcessor {
|
||||||
|
@ -8,7 +10,7 @@ export default class BlocksStreamProcessor {
|
||||||
this.lastUpdate = Date.now();
|
this.lastUpdate = Date.now();
|
||||||
this.isJsonStarted = false;
|
this.isJsonStarted = false;
|
||||||
this.jsonBuffer = '';
|
this.jsonBuffer = '';
|
||||||
this.lastDispatchedBlocks = null;
|
this.lastDispatchedBlocks = [];
|
||||||
this.renderDelay = 150;
|
this.renderDelay = 150;
|
||||||
|
|
||||||
// In Nginx server we have the true steaming experience and receive chunks in JS as soon as they are available.
|
// In Nginx server we have the true steaming experience and receive chunks in JS as soon as they are available.
|
||||||
|
@ -148,150 +150,7 @@ export default class BlocksStreamProcessor {
|
||||||
return '[]';
|
return '[]';
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = '';
|
return untruncateJson(partial);
|
||||||
let inString = false;
|
|
||||||
let inEscape = false;
|
|
||||||
let openBrackets = 0;
|
|
||||||
let openBraces = 0;
|
|
||||||
let lastPropertyName = '';
|
|
||||||
let inPropertyName = false;
|
|
||||||
let currentProperty = '';
|
|
||||||
const arrayStack = [];
|
|
||||||
const braceStack = [];
|
|
||||||
|
|
||||||
// Process character by character
|
|
||||||
for (let i = 0; i < partial.length; i++) {
|
|
||||||
const char = partial[i];
|
|
||||||
const nextChar = partial[i + 1];
|
|
||||||
result += char;
|
|
||||||
|
|
||||||
// Handle escape sequences
|
|
||||||
if (char === '\\\\' && inString) {
|
|
||||||
inEscape = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inEscape) {
|
|
||||||
inEscape = false;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Track string boundaries
|
|
||||||
if (char === '"' && !inEscape) {
|
|
||||||
if (!inString) {
|
|
||||||
inString = true;
|
|
||||||
|
|
||||||
// Check if this is a property name
|
|
||||||
if (!inPropertyName && nextChar === ':') {
|
|
||||||
inPropertyName = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
inString = false;
|
|
||||||
|
|
||||||
if (inPropertyName) {
|
|
||||||
lastPropertyName = currentProperty;
|
|
||||||
currentProperty = '';
|
|
||||||
inPropertyName = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (inString) {
|
|
||||||
if (inPropertyName) {
|
|
||||||
currentProperty += char;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only count structure characters outside strings
|
|
||||||
if (!inString) {
|
|
||||||
if (char === '[') {
|
|
||||||
openBrackets++;
|
|
||||||
arrayStack.push(i);
|
|
||||||
}
|
|
||||||
if (char === ']') {
|
|
||||||
openBrackets--;
|
|
||||||
if (arrayStack.length > 0) {
|
|
||||||
arrayStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (char === '{') {
|
|
||||||
openBraces++;
|
|
||||||
braceStack.push(i);
|
|
||||||
}
|
|
||||||
if (char === '}') {
|
|
||||||
openBraces--;
|
|
||||||
if (braceStack.length > 0) {
|
|
||||||
braceStack.pop();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete the structure
|
|
||||||
let completed = result;
|
|
||||||
|
|
||||||
// Handle unclosed strings
|
|
||||||
if (inString) {
|
|
||||||
completed += '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete property values if needed
|
|
||||||
if (lastPropertyName === 'content' && inString) {
|
|
||||||
completed += '"';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete objects and arrays from inside out
|
|
||||||
while (openBraces > 0) {
|
|
||||||
completed += '}';
|
|
||||||
openBraces--;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (openBrackets > 0) {
|
|
||||||
completed += ']';
|
|
||||||
openBrackets--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate and fix common issues
|
|
||||||
try {
|
|
||||||
JSON.parse(completed);
|
|
||||||
return completed;
|
|
||||||
} catch (e) {
|
|
||||||
// Try to fix common issues
|
|
||||||
let fixed = completed;
|
|
||||||
|
|
||||||
// Fix unclosed content property
|
|
||||||
const contentMatch = fixed.match(
|
|
||||||
/"content"\\s*:\\s*"([^"]*)(?:[^"]*)?$/
|
|
||||||
);
|
|
||||||
if (contentMatch) {
|
|
||||||
const contentEndIndex =
|
|
||||||
fixed.lastIndexOf(contentMatch[1]) + contentMatch[1].length;
|
|
||||||
fixed =
|
|
||||||
fixed.substring(0, contentEndIndex) +
|
|
||||||
'"' +
|
|
||||||
fixed.substring(contentEndIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fix missing commas between blocks
|
|
||||||
fixed = fixed.replace(/}(\\s*){/g, '},\\n{');
|
|
||||||
|
|
||||||
// Fix trailing commas
|
|
||||||
fixed = fixed.replace(/,(\\s*[}\\]])/g, '$1');
|
|
||||||
|
|
||||||
try {
|
|
||||||
JSON.parse(fixed);
|
|
||||||
return fixed;
|
|
||||||
} catch (e2) {
|
|
||||||
// If still invalid, try to extract valid parts
|
|
||||||
const blockMatch = fixed.match(
|
|
||||||
/\[\s*{[^{]*"name"\s*:\s*"[^"]+"\s*,\s*"attributes"\s*:\s*{[^}]+}/
|
|
||||||
);
|
|
||||||
if (blockMatch) {
|
|
||||||
return blockMatch[0] + '}]';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return minimal valid structure as last resort
|
|
||||||
return '[{"name":"core/paragraph","attributes":{"content":""},"innerBlocks":[]}]';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transformToBlock(blockData) {
|
transformToBlock(blockData) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue