Skip to content

Commit 0bb8449

Browse files
author
jiangtao.yang
committed
faet: init schema
1 parent 21fc2db commit 0bb8449

18 files changed

Lines changed: 566 additions & 138 deletions

File tree

apps/dsv/src/App.tsx

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,52 @@
11
import { useEffect, useState } from 'react';
22
import { run } from 'parser';
3+
34
function App() {
4-
const [count, setCount] = useState(0);
5+
const [code, setCode] = useState(`const bubbleSort = (arr) => {
6+
for (let i = 0; i < arr.length; i++) {
7+
for (let j = 0; j < arr.length - i - 1; j++) {
8+
if (arr[j] > arr[j + 1]) {
9+
let temp = arr[j];
10+
arr[j] = arr[j + 1];
11+
arr[j + 1] = temp;
12+
}
13+
}
14+
}
15+
return arr;
16+
}
17+
18+
const arr = [5, 3, 8, 4, 2];
19+
arr.pop()
20+
arr.push(1);
21+
bubbleSort(arr)
522
6-
useEffect(() => {
7-
run();
8-
}, []);
23+
console.log(arr)
24+
console.log(JSON.parse(JSON.stringify(arr)))
25+
`);
926

1027
return (
11-
<div>
12-
<button onClick={() => setCount((count) => count + 1)}>
13-
count is {count}
14-
</button>
28+
<div
29+
style={{
30+
display: 'flex',
31+
justifyContent: 'start',
32+
alignItems: 'center',
33+
height: '100vh',
34+
}}
35+
>
36+
<textarea
37+
style={{
38+
margin: '12px',
39+
width: '480px',
40+
height: '600px',
41+
padding: '12px',
42+
fontSize: '14px',
43+
fontFamily: 'monospace',
44+
}}
45+
placeholder="在此输入代码..."
46+
value={code}
47+
onChange={(e) => setCode(e.target.value)}
48+
/>
49+
<button onClick={() => run(code)}>Run</button>
1550
</div>
1651
);
1752
}

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
"description": "",
55
"main": "index.js",
66
"scripts": {
7-
"start": "pnpm --filter dsv dev",
7+
"dev": "concurrently \"pnpm --filter dsv dev\" \"pnpm --filter=schema dev\" \"pnpm --filter=parser dev\"",
88
"build": "pnpm -r build",
99
"test": "echo \"Error: no test specified\" && exit 1"
1010
},
1111
"keywords": [],
1212
"author": "",
13-
"license": "ISC"
13+
"license": "ISC",
14+
"devDependencies": {
15+
"concurrently": "^9.1.0"
16+
}
1417
}

packages/parser/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
{
22
"name": "parser",
3-
"version": "1.0.0",
3+
"version": "0.0.0",
44
"description": "",
55
"main": "dist/index.js",
66
"types": "dist/index.d.ts",
77
"scripts": {
8-
"build": "tsc"
8+
"build": "tsc",
9+
"dev": "tsc --watch"
910
},
1011
"keywords": [],
1112
"author": "",
1213
"license": "ISC",
1314
"dependencies": {
1415
"@babel/core": "^7.26.7",
15-
"@babel/types": "^7.26.7"
16+
"@babel/types": "^7.26.7",
17+
"schema": "workspace:*"
1618
},
1719
"devDependencies": {
1820
"typescript": "^5.0.0",

packages/parser/src/array-proxy.ts

Lines changed: 0 additions & 79 deletions
This file was deleted.
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
const uuid = (prefix) => {
2+
return (
3+
prefix +
4+
"-" +
5+
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
6+
const r = (Math.random() * 16) | 0;
7+
const v = c === "x" ? r : (r & 0x3) | 0x8;
8+
return v.toString(16);
9+
})
10+
);
11+
};
12+
13+
class ArrayProxy {
14+
constructor(array, options) {
15+
const id = uuid("ArrayProxy");
16+
const { snapshotSchema, schema, SchemaBuilder } = options;
17+
this.options = options;
18+
19+
snapshotSchema(
20+
new SchemaBuilder()
21+
.from(schema)
22+
.addStructure({
23+
id: id,
24+
type: "ArrayProxy",
25+
})
26+
.build()
27+
);
28+
29+
this.structureId = id;
30+
this.target = [...array];
31+
32+
const proxy = new Proxy(this.target, {
33+
get: (target, prop) => {
34+
if (prop === "__proxyGet") {
35+
return (index) => this._getHandler(target, index);
36+
}
37+
if (prop === "__proxySet") {
38+
return (index, value) => this._setHandler(target, index, value);
39+
}
40+
if (prop === "__proxyCall") {
41+
return (method, args) => {
42+
const fn = target[method];
43+
return this._applyHandler(fn, target, args, method);
44+
};
45+
}
46+
return this._getHandler(target, prop);
47+
},
48+
set: (target, prop, value) => this._setHandler(target, prop, value),
49+
});
50+
return proxy;
51+
}
52+
53+
_getHandler(target, prop) {
54+
const { snapshotSchema, schema, SchemaBuilder } = this.options;
55+
56+
const value = target[prop];
57+
if (typeof value === "function" && Array.prototype[prop]) {
58+
return (...args) => {
59+
const result = value.apply(target, args);
60+
61+
snapshotSchema(
62+
new SchemaBuilder()
63+
.from(schema)
64+
.addAction(this.structureId, {
65+
name: "call",
66+
type: prop,
67+
args: [...args],
68+
})
69+
.build()
70+
);
71+
return result;
72+
};
73+
}
74+
75+
if (typeof prop !== "symbol" && !isNaN(prop)) {
76+
snapshotSchema(
77+
new SchemaBuilder()
78+
.from(schema)
79+
.addAction(this.structureId, {
80+
name: "get",
81+
type: "get",
82+
args: [Number(prop)],
83+
})
84+
.build()
85+
);
86+
}
87+
88+
return value;
89+
}
90+
91+
_setHandler(target, prop, value) {
92+
const { snapshotSchema, schema, SchemaBuilder } = this.options;
93+
94+
const index = Number(prop);
95+
if (!isNaN(index)) {
96+
snapshotSchema(
97+
new SchemaBuilder()
98+
.from(schema)
99+
.addAction(this.structureId, {
100+
name: "set",
101+
type: "set",
102+
args: [index, value],
103+
})
104+
.build()
105+
);
106+
}
107+
target[prop] = value;
108+
return true;
109+
}
110+
111+
_applyHandler(target, thisArg, args, method) {
112+
const { snapshotSchema, schema, SchemaBuilder } = this.options;
113+
114+
const result = target.apply(thisArg, args);
115+
snapshotSchema(
116+
new SchemaBuilder()
117+
.from(schema)
118+
.addAction(this.structureId, {
119+
name: "call",
120+
type: method,
121+
args: [...args],
122+
})
123+
.build()
124+
);
125+
126+
if (Array.isArray(result)) {
127+
return new ArrayProxy(result, this.options);
128+
}
129+
return result;
130+
}
131+
}

0 commit comments

Comments
 (0)