Skip to content

Commit

Permalink
feat: optimize the proxy array
Browse files Browse the repository at this point in the history
  • Loading branch information
jiangtao.yang committed Feb 5, 2025
1 parent 0bb8449 commit 6ac16c4
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 199 deletions.
39 changes: 32 additions & 7 deletions apps/dsv/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,29 @@ import { useEffect, useState } from 'react';
import { run } from 'parser';

function App() {
const [code, setCode] = useState(`const bubbleSort = (arr) => {
const [code, setCode] = useState(`
// const bubbleSort = (arr) => {
// for (let i = 0; i < arr.length; i++) {
// for (let j = 0; j < arr.length - i - 1; j++) {
// if (arr[j] > arr[j + 1]) {
// let temp = arr[j];
// arr[j] = arr[j + 1];
// arr[j + 1] = temp;
// }
// }
// }
// return arr;
// }
// const arr = [5, 3, 8, 4, 2];
// arr.pop()
// arr.push(1);
// bubbleSort(arr)
// console.log(arr)
// console.log(JSON.parse(JSON.stringify(arr)))
const bubbleSort = (arr) => {
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr.length - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
Expand All @@ -15,13 +37,16 @@ function App() {
return arr;
}
const arr = [5, 3, 8, 4, 2];
arr.pop()
arr.push(1);
bubbleSort(arr)
const arr1 = [5, 3, 8, 4, 2];
const arr2 = [1, 2, 4]
const arr3 = arr1.concat(arr2)
bubbleSort(arr3)
console.log(arr3)
console.log(JSON.parse(JSON.stringify(arr3)))
console.log(arr)
console.log(JSON.parse(JSON.stringify(arr)))
`);

return (
Expand Down
131 changes: 0 additions & 131 deletions packages/parser/src/data-structures/array/array-proxy.temp.js

This file was deleted.

75 changes: 38 additions & 37 deletions packages/parser/src/data-structures/array/array-proxy.ts
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
export const ArrayProxyString = `
const uuid = (prefix) => {
return (
prefix +
"-" +
"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0;
const v = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
})
);
};
import { Schema, SchemaBuilder, StructureType } from "schema";

class ArrayProxy {
constructor(array, options) {
const id = uuid("ArrayProxy");
const { snapshotSchema, schema, SchemaBuilder } = options;
this.options = options;
interface ArrayProxyOptions {
snapshotSchema: (schema: Schema) => void;
schema: Schema;
SchemaBuilder: typeof SchemaBuilder;
uuid: (prefix: string) => string;
}

export class ArrayProxy {
structureId: string;
options: ArrayProxyOptions;
target: any[];

constructor(array: any[], options: ArrayProxyOptions) {
const { snapshotSchema, schema, SchemaBuilder, uuid } = options;
this.structureId = uuid("array");
this.options = options;
snapshotSchema(
new SchemaBuilder()
.from(schema)
.addStructure({
id: id,
type: "ArrayProxy",
id: this.structureId,
type: StructureType.Array,
array,
})
.build()
);

this.structureId = id;
this.target = [...array];

const proxy = new Proxy(this.target, {
get: (target, prop) => {
if (prop === "__proxyGet") {
return (index) => this._getHandler(target, index);
return (index: number) => this._getHandler(target, index);
}
if (prop === "__proxySet") {
return (index, value) => this._setHandler(target, index, value);
return (index: number, value: any) =>
this._setHandler(target, index, value);
}
if (prop === "__proxyCall") {
return (method, args) => {
const fn = target[method];
return (method: string, args: any[]) => {
const fn = target[method as keyof typeof target];
return this._applyHandler(fn, target, args, method);
};
}
Expand All @@ -51,20 +51,21 @@ class ArrayProxy {
return proxy;
}

_getHandler(target, prop) {
_getHandler(target: any[], prop: number) {
const { snapshotSchema, schema, SchemaBuilder } = this.options;

const value = target[prop];
if (typeof value === "function" && Array.prototype[prop]) {
return (...args) => {
return (...args: any[]) => {
const result = value.apply(target, args);

snapshotSchema(
new SchemaBuilder()
.from(schema)
.addAction(this.structureId, {
.addAction({
structureId: this.structureId,
name: "call",
type: prop,
type: prop.toString(),
args: [...args],
})
.build()
Expand All @@ -77,7 +78,8 @@ class ArrayProxy {
snapshotSchema(
new SchemaBuilder()
.from(schema)
.addAction(this.structureId, {
.addAction({
structureId: this.structureId,
name: "get",
type: "get",
args: [Number(prop)],
Expand All @@ -89,15 +91,16 @@ class ArrayProxy {
return value;
}

_setHandler(target, prop, value) {
_setHandler(target: any[], prop: number, value: any) {
const { snapshotSchema, schema, SchemaBuilder } = this.options;

const index = Number(prop);
if (!isNaN(index)) {
snapshotSchema(
new SchemaBuilder()
.from(schema)
.addAction(this.structureId, {
.addAction({
structureId: this.structureId,
name: "set",
type: "set",
args: [index, value],
Expand All @@ -109,14 +112,15 @@ class ArrayProxy {
return true;
}

_applyHandler(target, thisArg, args, method) {
_applyHandler(fn: Function, thisArg: any, args: any[], method: string) {
const { snapshotSchema, schema, SchemaBuilder } = this.options;

const result = target.apply(thisArg, args);
const result = fn.apply(thisArg, args);
snapshotSchema(
new SchemaBuilder()
.from(schema)
.addAction(this.structureId, {
.addAction({
structureId: this.structureId,
name: "call",
type: method,
args: [...args],
Expand All @@ -130,6 +134,3 @@ class ArrayProxy {
return result;
}
}
`;
14 changes: 14 additions & 0 deletions packages/parser/src/data-structures/array/array-visitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ export const arrayVisitor = {
return;
}

// 检查父节点是否为 __proxyCall 的参数
const parent = path.parentPath;
if (parent.isCallExpression()) {
const callee = parent.node.callee;
if (
t.isMemberExpression(callee) &&
t.isIdentifier(callee.property, { name: "__proxyCall" })
) {
// 如果是 __proxyCall 的参数,跳过转换
return;
}
}

// 创建内部数组时标记为已转换
const innerArray = t.arrayExpression(path.node.elements);
(innerArray as any).wasConverted = true;
Expand Down Expand Up @@ -37,6 +50,7 @@ export const arrayVisitor = {
"splice",
"sort",
"reverse",
"concat",
].includes(node.callee.property.name)
) {
const proxyCall = t.callExpression(
Expand Down
8 changes: 5 additions & 3 deletions packages/parser/src/execute/executeCode.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
import { logStyle } from "../utils/log";
import { Schema, SchemaBuilder } from "schema";
import { uuid } from "../utils/uuid";
import { ArrayProxy } from "../data-structures/array/array-proxy";
// 执行代码
export const executeCode = (code: string) => {
try {
console.groupCollapsed("%cExecuted Result", logStyle);

const exeFunc = new Function("__GlobalContext__", code);
const exeFunc = new Function("ArrayProxy", "__GlobalContext__", code);

const __GlobalContext__: Record<string, any> = {
uuid,
schema: {},
SchemaBuilder,
snapshotSchema: (schema: Schema) => {
__GlobalContext__.schema = schema;
},
};

const result = exeFunc(__GlobalContext__);
const result = exeFunc(ArrayProxy, __GlobalContext__);

result && console.log(result);
__GlobalContext__ && console.log(__GlobalContext__);
Expand Down
Loading

0 comments on commit 6ac16c4

Please sign in to comment.