@appthen/cli 1.2.10 → 1.2.11
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/.gitignore +1 -0
- package/bin/main.js +45 -0
- package/dist/index.js +1108 -267
- package/package.json +1 -1
- package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1406 -0
- package/tests/test-app/.appthen/shadow-space-unknown-user-test-app-e99876b1.json +1060 -0
- package/tests/test-app/.appthen/space-config.json +8 -0
- package/tests/test-app/docs/AI-Workflow.flow +112 -0
- package/tests/test-app/docs/Logic-1.flow +16 -0
- package/tests/test-app/docs/Logic.flow +16 -0
- package/tests/test-app/docs/Project-Blueprint-1.flow +119 -0
- package/tests/test-app/docs/Project-Blueprint.flow +119 -0
- package/tests/test-app/docs/README.md +3 -0
- package/tests/test-app/docs/claude.md +194 -0
- package/tests/test-app/docs/page_requirement_analysis.md +149 -0
- package/tests/test-app/docs//345/267/245/345/215/225/347/256/241/347/220/206/347/263/273/347/273/237/350/257/246/347/273/206/350/256/276/350/256/241.md +377 -0
- package/tests/test-app/src/apis/AddTodoPost.api.ts +42 -0
- package/tests/test-app/src/apis/DeleteTodoPost.api.ts +32 -0
- package/tests/test-app/src/apis/GetListPost.api.ts +38 -0
- package/tests/test-app/src/apis/TicketAttachmentUploadPost.api.ts +42 -0
- package/tests/test-app/src/apis/UpdateTodoPost.api.ts +46 -0
- package/tests/test-app/src/app.css +15 -0
- package/tests/test-app/src/cloud_functions/ticket|attachment|upload.node.ts +86 -0
- package/tests/test-app/src/cloud_functions/ticket|comment|add.node.ts +65 -0
- package/tests/test-app/src/cloud_functions/types|entity|Ticket.node.ts +88 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketAttachment.node.ts +70 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketCategory.node.ts +56 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketComment.node.ts +62 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketHistory.node.ts +74 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketPriority.node.ts +68 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketStatus.node.ts +63 -0
- package/tests/test-app/src/cloud_functions/types|models|CreateTicketParams.node.ts +20 -0
- package/tests/test-app/src/cloud_functions/types|models|TicketListParams.node.ts +30 -0
- package/tests/test-app/src/cloud_functions/types|models|UpdateTicketParams.node.ts +22 -0
- package/tests/test-app/src/components/Button.js +11 -0
- package/tests/test-app/src/components/MouduleDemoNzp.tsx +40 -0
- package/tests/test-app/src/components/Timeline.tsx +145 -0
- package/tests/test-app/src/index.ts +2 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketCommentAddPost.api.ts +48 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketCreatePost.api.ts +52 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketDeleteDelete.api.ts +39 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketDetailGet.api.ts +39 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketListGet.api.ts +61 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketUpdatePut.api.ts +57 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorFaultListGet.ts +76 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorListGet.ts +76 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorOperationRecordsGet.ts +284 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorStatisticsGet.ts +96 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/category|list.node.ts +40 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/priority|list.node.ts +26 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/status|list.node.ts +26 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|create.node.ts +54 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|delete.node.ts +55 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|detail.node.ts +65 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|list.node.ts +85 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|update.node.ts +73 -0
- package/tests/test-app/src/modules/work_order_module/data_model/Ticket.m.ts +85 -0
- package/tests/test-app/src/modules/work_order_module/data_model/TicketCategory.m.ts +53 -0
- package/tests/test-app/src/modules/work_order_module/data_model/TicketStatus.m.ts +60 -0
- package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/344/272/247/345/223/201/350/256/276/350/256/241/346/226/207/346/241/243.md +301 -0
- package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/345/274/200/345/217/221/344/273/273/345/212/241/345/210/206/345/267/245/346/226/207/346/241/243.md +345 -0
- package/tests/test-app/src/pages/SLAManagement.tsx +668 -0
- package/tests/test-app/src/pages/TicketCreate.tsx +27 -0
- package/tests/test-app/src/pages/TicketDetail.tsx +27 -0
- package/tests/test-app/src/pages/TicketList.tsx +27 -0
- package/tests/test-app/src/pages/TicketManagementPage.tsx +1238 -0
- package/tests/test-app/src/pages/VisualAIIDEUpgrade.tsx +245 -0
- package/tests/test-app/src/pages/appthen_guide/ComponentTreeUnderstanding.tsx +26 -0
- package/tests/test-app/src/pages/appthen_guide/DataBindingLearning.tsx +26 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout.tsx +155 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout10.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout2.tsx +156 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout3.tsx +156 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout4.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout5.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout6.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout7.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout8.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout9.tsx +157 -0
- package/tests/test-app/src/pages/back-end/backgroundManagementSystem.css +5 -0
- package/tests/test-app/src/pages/back-end/backgroundManagementSystem.tsx +1745 -0
- package/tests/test-app/src/pages/component/WorkOrderCard.tsx +140 -0
- package/tests/test-app/src/pages/cover.tsx +42 -0
- package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.css +181 -0
- package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.tsx +225 -0
- package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.css +181 -0
- package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.tsx +138 -0
- package/tests/test-app/src/pages/data_dashboard/component_library/BlueBrightGreenBorder.tsx +47 -0
- package/tests/test-app/src/pages/data_dashboard/component_library/FullScreenContainer.tsx +133 -0
- package/tests/test-app/src/pages/description_of_mock_interface.md +32 -0
- package/tests/test-app/src/pages/digitalLargeScreen.css +181 -0
- package/tests/test-app/src/pages/digitalLargeScreen.tsx +1417 -0
- package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.css +3 -0
- package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.tsx +362 -0
- package/tests/test-app/src/pages/mobile_terminal/WorkOrderHomepage.tsx +337 -0
- package/tests/test-app/src/pages/mobile_terminal/newWorkOrder.tsx +224 -0
- package/tests/test-app/src/pages/mobile_terminal/tabbar.tsx +67 -0
- package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +638 -0
- package/tests/test-app/src/pages/mobile_terminal/workOrderDetails.tsx +346 -0
- package/tests/test-app/src/pages/mobile_terminal/workOrderPage.tsx +345 -0
- package/tests/test-app/src/pages/testPage.css +3 -0
- package/tests/test-app/src/pages/testPage.tsx +158 -0
- package/tests/test-app/src/pages/web_version/website.css +205 -0
- package/tests/test-app/src/pages/web_version/website.tsx +1066 -0
- package/tests/test-app/src/pages//345/276/205/345/212/236.apidoc.json +336 -0
- package/tests/test-app/src/project.json +1120 -0
- package/tests/test-app/src/store/global.store.ts +10 -0
- package/tests/test-app/src/types/CreateTicketParams.m.ts +20 -0
- package/tests/test-app/src/types/SLAPolicy.ts +50 -0
- package/tests/test-app/src/types/Ticket.ts +68 -0
- package/tests/test-app/src/types/TicketAttachment.m.ts +67 -0
- package/tests/test-app/src/types/TicketComment.m.ts +59 -0
- package/tests/test-app/src/types/TicketEvaluation.ts +44 -0
- package/tests/test-app/src/types/TicketHistory.m.ts +71 -0
- package/tests/test-app/src/types/TicketListParams.m.ts +30 -0
- package/tests/test-app/src/types/TicketPriority.m.ts +65 -0
- package/tests/test-app/src/types/TicketRecord.ts +47 -0
- package/tests/test-app/src/types/TrainDoor.ts +284 -0
- package/tests/test-app/src/types/UpdateTicketParams.m.ts +22 -0
- package/tests/test-app/src/utils/__afterRequest.util.ts +3 -0
- package/tests/test-app/src/utils/__beforeRequest.util.ts +10 -0
- package/tests/test-app/src/utils/testGlobalAction.util.ts +7 -0
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ var prettier = require('prettier');
|
|
|
29
29
|
var fs$2 = require('fs-extra');
|
|
30
30
|
var io = require('socket.io-client');
|
|
31
31
|
var fs$3 = require('fs/promises');
|
|
32
|
+
var chokidar = require('chokidar');
|
|
32
33
|
var whatwgUrl = require('whatwg-url');
|
|
33
34
|
|
|
34
35
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -80,6 +81,7 @@ var fs__default$1 = /*#__PURE__*/_interopDefaultLegacy(fs$2);
|
|
|
80
81
|
var fs__namespace$1 = /*#__PURE__*/_interopNamespace(fs$2);
|
|
81
82
|
var io__default = /*#__PURE__*/_interopDefaultLegacy(io);
|
|
82
83
|
var fs__default$2 = /*#__PURE__*/_interopDefaultLegacy(fs$3);
|
|
84
|
+
var chokidar__default = /*#__PURE__*/_interopDefaultLegacy(chokidar);
|
|
83
85
|
var whatwgUrl__default = /*#__PURE__*/_interopDefaultLegacy(whatwgUrl);
|
|
84
86
|
|
|
85
87
|
/******************************************************************************
|
|
@@ -2803,36 +2805,29 @@ browser$1.destroy;
|
|
|
2803
2805
|
browser$1.colors;
|
|
2804
2806
|
browser$1.log;
|
|
2805
2807
|
|
|
2806
|
-
var hasFlag = (flag, argv
|
|
2808
|
+
var hasFlag = (flag, argv) => {
|
|
2809
|
+
argv = argv || process.argv;
|
|
2807
2810
|
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
|
|
2808
|
-
const
|
|
2809
|
-
const
|
|
2810
|
-
return
|
|
2811
|
+
const pos = argv.indexOf(prefix + flag);
|
|
2812
|
+
const terminatorPos = argv.indexOf('--');
|
|
2813
|
+
return pos !== -1 && (terminatorPos === -1 ? true : pos < terminatorPos);
|
|
2811
2814
|
};
|
|
2812
2815
|
|
|
2813
|
-
const
|
|
2816
|
+
const env = process.env;
|
|
2814
2817
|
|
|
2815
2818
|
let forceColor;
|
|
2816
2819
|
if (hasFlag('no-color') ||
|
|
2817
2820
|
hasFlag('no-colors') ||
|
|
2818
|
-
hasFlag('color=false')
|
|
2819
|
-
|
|
2820
|
-
forceColor = 0;
|
|
2821
|
+
hasFlag('color=false')) {
|
|
2822
|
+
forceColor = false;
|
|
2821
2823
|
} else if (hasFlag('color') ||
|
|
2822
2824
|
hasFlag('colors') ||
|
|
2823
2825
|
hasFlag('color=true') ||
|
|
2824
2826
|
hasFlag('color=always')) {
|
|
2825
|
-
forceColor =
|
|
2827
|
+
forceColor = true;
|
|
2826
2828
|
}
|
|
2827
|
-
|
|
2828
2829
|
if ('FORCE_COLOR' in env) {
|
|
2829
|
-
|
|
2830
|
-
forceColor = 1;
|
|
2831
|
-
} else if (env.FORCE_COLOR === 'false') {
|
|
2832
|
-
forceColor = 0;
|
|
2833
|
-
} else {
|
|
2834
|
-
forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
|
|
2835
|
-
}
|
|
2830
|
+
forceColor = env.FORCE_COLOR.length === 0 || parseInt(env.FORCE_COLOR, 10) !== 0;
|
|
2836
2831
|
}
|
|
2837
2832
|
|
|
2838
2833
|
function translateLevel(level) {
|
|
@@ -2848,8 +2843,8 @@ function translateLevel(level) {
|
|
|
2848
2843
|
};
|
|
2849
2844
|
}
|
|
2850
2845
|
|
|
2851
|
-
function supportsColor(
|
|
2852
|
-
if (forceColor ===
|
|
2846
|
+
function supportsColor(stream) {
|
|
2847
|
+
if (forceColor === false) {
|
|
2853
2848
|
return 0;
|
|
2854
2849
|
}
|
|
2855
2850
|
|
|
@@ -2863,21 +2858,22 @@ function supportsColor(haveStream, streamIsTTY) {
|
|
|
2863
2858
|
return 2;
|
|
2864
2859
|
}
|
|
2865
2860
|
|
|
2866
|
-
if (
|
|
2861
|
+
if (stream && !stream.isTTY && forceColor !== true) {
|
|
2867
2862
|
return 0;
|
|
2868
2863
|
}
|
|
2869
2864
|
|
|
2870
|
-
const min = forceColor
|
|
2871
|
-
|
|
2872
|
-
if (env.TERM === 'dumb') {
|
|
2873
|
-
return min;
|
|
2874
|
-
}
|
|
2865
|
+
const min = forceColor ? 1 : 0;
|
|
2875
2866
|
|
|
2876
2867
|
if (process.platform === 'win32') {
|
|
2877
|
-
//
|
|
2878
|
-
//
|
|
2868
|
+
// Node.js 7.5.0 is the first version of Node.js to include a patch to
|
|
2869
|
+
// libuv that enables 256 color output on Windows. Anything earlier and it
|
|
2870
|
+
// won't work. However, here we target Node.js 8 at minimum as it is an LTS
|
|
2871
|
+
// release, and Node.js 7 is not. Windows 10 build 10586 is the first Windows
|
|
2872
|
+
// release that supports 256 colors. Windows 10 build 14931 is the first release
|
|
2873
|
+
// that supports 16m/TrueColor.
|
|
2879
2874
|
const osRelease = os__default["default"].release().split('.');
|
|
2880
2875
|
if (
|
|
2876
|
+
Number(process.versions.node.split('.')[0]) >= 8 &&
|
|
2881
2877
|
Number(osRelease[0]) >= 10 &&
|
|
2882
2878
|
Number(osRelease[2]) >= 10586
|
|
2883
2879
|
) {
|
|
@@ -2888,7 +2884,7 @@ function supportsColor(haveStream, streamIsTTY) {
|
|
|
2888
2884
|
}
|
|
2889
2885
|
|
|
2890
2886
|
if ('CI' in env) {
|
|
2891
|
-
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'
|
|
2887
|
+
if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
|
|
2892
2888
|
return 1;
|
|
2893
2889
|
}
|
|
2894
2890
|
|
|
@@ -2927,18 +2923,22 @@ function supportsColor(haveStream, streamIsTTY) {
|
|
|
2927
2923
|
return 1;
|
|
2928
2924
|
}
|
|
2929
2925
|
|
|
2926
|
+
if (env.TERM === 'dumb') {
|
|
2927
|
+
return min;
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2930
2930
|
return min;
|
|
2931
2931
|
}
|
|
2932
2932
|
|
|
2933
2933
|
function getSupportLevel(stream) {
|
|
2934
|
-
const level = supportsColor(stream
|
|
2934
|
+
const level = supportsColor(stream);
|
|
2935
2935
|
return translateLevel(level);
|
|
2936
2936
|
}
|
|
2937
2937
|
|
|
2938
2938
|
var supportsColor_1 = {
|
|
2939
2939
|
supportsColor: getSupportLevel,
|
|
2940
|
-
stdout:
|
|
2941
|
-
stderr:
|
|
2940
|
+
stdout: getSupportLevel(process.stdout),
|
|
2941
|
+
stderr: getSupportLevel(process.stderr)
|
|
2942
2942
|
};
|
|
2943
2943
|
supportsColor_1.supportsColor;
|
|
2944
2944
|
supportsColor_1.stdout;
|
|
@@ -17179,7 +17179,7 @@ FormData$2.prototype.submit = function (params, cb) {
|
|
|
17179
17179
|
request.removeListener('error', callback);
|
|
17180
17180
|
request.removeListener('response', onResponse);
|
|
17181
17181
|
|
|
17182
|
-
return cb.call(this, error, responce);
|
|
17182
|
+
return cb.call(this, error, responce);
|
|
17183
17183
|
};
|
|
17184
17184
|
|
|
17185
17185
|
onResponse = callback.bind(this, null);
|
|
@@ -17203,7 +17203,7 @@ FormData$2.prototype._error = function (err) {
|
|
|
17203
17203
|
FormData$2.prototype.toString = function () {
|
|
17204
17204
|
return '[object FormData]';
|
|
17205
17205
|
};
|
|
17206
|
-
setToStringTag(FormData$2, 'FormData');
|
|
17206
|
+
setToStringTag(FormData$2.prototype, 'FormData');
|
|
17207
17207
|
|
|
17208
17208
|
// Public API
|
|
17209
17209
|
var form_data = FormData$2;
|
|
@@ -18819,9 +18819,8 @@ var request = function (url, params, _a) {
|
|
|
18819
18819
|
};
|
|
18820
18820
|
return [4 /*yield*/, axios({
|
|
18821
18821
|
method: method,
|
|
18822
|
-
url: (process.env.DEV
|
|
18823
|
-
|
|
18824
|
-
: 'https://editor.appthen.com') + url,
|
|
18822
|
+
url: (process.env.DEV ? 'http://127.0.0.1:1626' : 'https://api.appthen.com') +
|
|
18823
|
+
url,
|
|
18825
18824
|
data: params,
|
|
18826
18825
|
headers: headers,
|
|
18827
18826
|
})];
|
|
@@ -37899,7 +37898,7 @@ function create(options) {
|
|
|
37899
37898
|
|
|
37900
37899
|
var fuck = function () { };
|
|
37901
37900
|
|
|
37902
|
-
var server = 'wss://
|
|
37901
|
+
var server = 'wss://api.appthen.com';
|
|
37903
37902
|
var devServer = 'ws://127.0.0.1:1626';
|
|
37904
37903
|
var DEV_MODE$1 = process.env.DEV;
|
|
37905
37904
|
var SocketStore = /** @class */ (function () {
|
|
@@ -40668,8 +40667,13 @@ function regExpEscape (s) {
|
|
|
40668
40667
|
return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&')
|
|
40669
40668
|
}
|
|
40670
40669
|
|
|
40671
|
-
|
|
40672
|
-
var
|
|
40670
|
+
var logger = function () {
|
|
40671
|
+
var args = [];
|
|
40672
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
40673
|
+
args[_i] = arguments[_i];
|
|
40674
|
+
}
|
|
40675
|
+
console.log.apply(console, __spreadArray([], __read(args), false));
|
|
40676
|
+
};
|
|
40673
40677
|
/**
|
|
40674
40678
|
* 影子空间管理器
|
|
40675
40679
|
* 维护编辑器状态的本地镜像,用于检测文件变更
|
|
@@ -40951,6 +40955,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
40951
40955
|
return [4 /*yield*/, fs__default$1["default"].unlink(fullPath)];
|
|
40952
40956
|
case 2:
|
|
40953
40957
|
_a.sent();
|
|
40958
|
+
logger("\u672C\u5730\u6587\u4EF6\u5DF2\u5220\u9664: ".concat(fullPath));
|
|
40954
40959
|
return [3 /*break*/, 4];
|
|
40955
40960
|
case 3:
|
|
40956
40961
|
error_1 = _a.sent();
|
|
@@ -40964,6 +40969,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
40964
40969
|
return [4 /*yield*/, this.saveState()];
|
|
40965
40970
|
case 5:
|
|
40966
40971
|
_a.sent();
|
|
40972
|
+
logger("\u5F71\u5B50\u7A7A\u95F4\u6587\u4EF6\u5DF2\u5220\u9664: ".concat(filePath));
|
|
40967
40973
|
return [2 /*return*/, true];
|
|
40968
40974
|
}
|
|
40969
40975
|
});
|
|
@@ -40975,33 +40981,33 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
40975
40981
|
*/
|
|
40976
40982
|
ShadowSpace.prototype.detectChanges = function () {
|
|
40977
40983
|
return __awaiter(this, void 0, void 0, function () {
|
|
40978
|
-
var changes, _a, _b, _c, filePath, shadowEntry, localFilePath, localContent, localHash, fileStat, fileModifyTime, shadowContent, _d, _e, error_2, shadowContent, e_3_1, localFiles, localFiles_1, localFiles_1_1, localFile;
|
|
40979
|
-
var e_3, _f, _g, e_4, _h;
|
|
40980
|
-
return __generator(this, function (
|
|
40981
|
-
switch (
|
|
40984
|
+
var changes, _a, _b, _c, filePath, shadowEntry, localFilePath, localContent, localHash, fileStat, fileModifyTime, shadowContent, _d, _e, error_2, shadowContent, e_3_1, localFiles, localFiles_1, localFiles_1_1, localFile, tempNormalizePath, addsFromRemote, addsFromLocal, _loop_1, addsFromRemote_1, addsFromRemote_1_1, remoteAdd;
|
|
40985
|
+
var e_3, _f, _g, e_4, _h, e_5, _j;
|
|
40986
|
+
return __generator(this, function (_k) {
|
|
40987
|
+
switch (_k.label) {
|
|
40982
40988
|
case 0:
|
|
40983
40989
|
changes = [];
|
|
40984
|
-
|
|
40990
|
+
_k.label = 1;
|
|
40985
40991
|
case 1:
|
|
40986
|
-
|
|
40992
|
+
_k.trys.push([1, 16, 17, 18]);
|
|
40987
40993
|
_a = __values(Object.entries(this.state.files)), _b = _a.next();
|
|
40988
|
-
|
|
40994
|
+
_k.label = 2;
|
|
40989
40995
|
case 2:
|
|
40990
40996
|
if (!!_b.done) return [3 /*break*/, 15];
|
|
40991
40997
|
_c = __read(_b.value, 2), filePath = _c[0], shadowEntry = _c[1];
|
|
40992
40998
|
localFilePath = path__default["default"].join(this.config.projectRoot, filePath);
|
|
40993
|
-
|
|
40999
|
+
_k.label = 3;
|
|
40994
41000
|
case 3:
|
|
40995
|
-
|
|
41001
|
+
_k.trys.push([3, 11, , 14]);
|
|
40996
41002
|
return [4 /*yield*/, fs__default$1["default"].readFile(localFilePath, 'utf8')];
|
|
40997
41003
|
case 4:
|
|
40998
|
-
localContent =
|
|
41004
|
+
localContent = _k.sent();
|
|
40999
41005
|
localHash = this.calculateHash(localContent);
|
|
41000
41006
|
if (!(localHash !== shadowEntry.hash)) return [3 /*break*/, 10];
|
|
41001
41007
|
if (!shadowEntry.remoteModified) return [3 /*break*/, 7];
|
|
41002
41008
|
return [4 /*yield*/, fs__default$1["default"].stat(localFilePath)];
|
|
41003
41009
|
case 5:
|
|
41004
|
-
fileStat =
|
|
41010
|
+
fileStat = _k.sent();
|
|
41005
41011
|
fileModifyTime = fileStat.mtimeMs;
|
|
41006
41012
|
// logger(`[ShadowSpace] 🔍 更新文件时间戳: ${filePath}`, {
|
|
41007
41013
|
// 旧lastModified: new Date(
|
|
@@ -41017,12 +41023,12 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41017
41023
|
return [4 /*yield*/, this.saveState()];
|
|
41018
41024
|
case 6:
|
|
41019
41025
|
// 保存状态
|
|
41020
|
-
|
|
41026
|
+
_k.sent();
|
|
41021
41027
|
// 🔥 跳过,不添加到 changes
|
|
41022
41028
|
return [3 /*break*/, 14];
|
|
41023
41029
|
case 7: return [4 /*yield*/, this.getShadowContent(filePath)];
|
|
41024
41030
|
case 8:
|
|
41025
|
-
shadowContent =
|
|
41031
|
+
shadowContent = _k.sent();
|
|
41026
41032
|
_e = (_d = changes).push;
|
|
41027
41033
|
_g = {
|
|
41028
41034
|
id: this.generateId(),
|
|
@@ -41032,21 +41038,21 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41032
41038
|
};
|
|
41033
41039
|
return [4 /*yield*/, fs__default$1["default"].stat(localFilePath)];
|
|
41034
41040
|
case 9:
|
|
41035
|
-
_e.apply(_d, [(_g.timestamp = (
|
|
41041
|
+
_e.apply(_d, [(_g.timestamp = (_k.sent()).mtime.getTime(),
|
|
41036
41042
|
_g.diff = {
|
|
41037
41043
|
before: shadowContent,
|
|
41038
41044
|
after: localContent,
|
|
41039
41045
|
},
|
|
41040
41046
|
_g.projectId = this.state.projectId,
|
|
41041
41047
|
_g)]);
|
|
41042
|
-
|
|
41048
|
+
_k.label = 10;
|
|
41043
41049
|
case 10: return [3 /*break*/, 14];
|
|
41044
41050
|
case 11:
|
|
41045
|
-
error_2 =
|
|
41051
|
+
error_2 = _k.sent();
|
|
41046
41052
|
if (!(error_2.code === 'ENOENT')) return [3 /*break*/, 13];
|
|
41047
41053
|
return [4 /*yield*/, this.getShadowContent(filePath)];
|
|
41048
41054
|
case 12:
|
|
41049
|
-
shadowContent =
|
|
41055
|
+
shadowContent = _k.sent();
|
|
41050
41056
|
changes.push({
|
|
41051
41057
|
id: this.generateId(),
|
|
41052
41058
|
action: 'delete',
|
|
@@ -41059,14 +41065,14 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41059
41065
|
},
|
|
41060
41066
|
projectId: this.state.projectId,
|
|
41061
41067
|
});
|
|
41062
|
-
|
|
41068
|
+
_k.label = 13;
|
|
41063
41069
|
case 13: return [3 /*break*/, 14];
|
|
41064
41070
|
case 14:
|
|
41065
41071
|
_b = _a.next();
|
|
41066
41072
|
return [3 /*break*/, 2];
|
|
41067
41073
|
case 15: return [3 /*break*/, 18];
|
|
41068
41074
|
case 16:
|
|
41069
|
-
e_3_1 =
|
|
41075
|
+
e_3_1 = _k.sent();
|
|
41070
41076
|
e_3 = { error: e_3_1 };
|
|
41071
41077
|
return [3 /*break*/, 18];
|
|
41072
41078
|
case 17:
|
|
@@ -41077,7 +41083,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41077
41083
|
return [7 /*endfinally*/];
|
|
41078
41084
|
case 18: return [4 /*yield*/, this.scanLocalFiles()];
|
|
41079
41085
|
case 19:
|
|
41080
|
-
localFiles =
|
|
41086
|
+
localFiles = _k.sent();
|
|
41081
41087
|
try {
|
|
41082
41088
|
for (localFiles_1 = __values(localFiles), localFiles_1_1 = localFiles_1.next(); !localFiles_1_1.done; localFiles_1_1 = localFiles_1.next()) {
|
|
41083
41089
|
localFile = localFiles_1_1.value;
|
|
@@ -41104,6 +41110,53 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41104
41110
|
}
|
|
41105
41111
|
finally { if (e_4) throw e_4.error; }
|
|
41106
41112
|
}
|
|
41113
|
+
tempNormalizePath = function (p) { return p.replace(/\\/g, '/'); };
|
|
41114
|
+
addsFromRemote = changes.filter(function (c) { return c.action === 'add' && c.side === 'editor'; });
|
|
41115
|
+
addsFromLocal = changes.filter(function (c) { return c.action === 'add' && c.side === 'space'; });
|
|
41116
|
+
_loop_1 = function (remoteAdd) {
|
|
41117
|
+
var localAdd = addsFromLocal.find(function (l) {
|
|
41118
|
+
return tempNormalizePath(l.path) === tempNormalizePath(remoteAdd.path);
|
|
41119
|
+
});
|
|
41120
|
+
if (localAdd) {
|
|
41121
|
+
// 发现双向 Add,说明 Map Key 匹配失败了,但路径标准化后是一样的
|
|
41122
|
+
console.error("[ShadowSpace] CRITICAL: Detected dual ADD for ".concat(remoteAdd.path, ". Merging to CONFLICT."));
|
|
41123
|
+
// 移除这两个 Add
|
|
41124
|
+
var indexR = changes.indexOf(remoteAdd);
|
|
41125
|
+
if (indexR > -1)
|
|
41126
|
+
changes.splice(indexR, 1);
|
|
41127
|
+
var indexL = changes.indexOf(localAdd);
|
|
41128
|
+
if (indexL > -1)
|
|
41129
|
+
changes.splice(indexL, 1);
|
|
41130
|
+
// 添加一个 Modify Conflict
|
|
41131
|
+
changes.push({
|
|
41132
|
+
action: 'modify',
|
|
41133
|
+
path: tempNormalizePath(remoteAdd.path),
|
|
41134
|
+
side: 'editor',
|
|
41135
|
+
sourceLabel: 'remote',
|
|
41136
|
+
targetLabel: 'local',
|
|
41137
|
+
// @ts-ignore
|
|
41138
|
+
editorHash: remoteAdd.editorHash,
|
|
41139
|
+
// @ts-ignore
|
|
41140
|
+
spaceHash: localAdd.spaceHash,
|
|
41141
|
+
conflict: true,
|
|
41142
|
+
// @ts-ignore
|
|
41143
|
+
debug: 'merged_dual_add',
|
|
41144
|
+
});
|
|
41145
|
+
}
|
|
41146
|
+
};
|
|
41147
|
+
try {
|
|
41148
|
+
for (addsFromRemote_1 = __values(addsFromRemote), addsFromRemote_1_1 = addsFromRemote_1.next(); !addsFromRemote_1_1.done; addsFromRemote_1_1 = addsFromRemote_1.next()) {
|
|
41149
|
+
remoteAdd = addsFromRemote_1_1.value;
|
|
41150
|
+
_loop_1(remoteAdd);
|
|
41151
|
+
}
|
|
41152
|
+
}
|
|
41153
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
41154
|
+
finally {
|
|
41155
|
+
try {
|
|
41156
|
+
if (addsFromRemote_1_1 && !addsFromRemote_1_1.done && (_j = addsFromRemote_1.return)) _j.call(addsFromRemote_1);
|
|
41157
|
+
}
|
|
41158
|
+
finally { if (e_5) throw e_5.error; }
|
|
41159
|
+
}
|
|
41107
41160
|
return [2 /*return*/, changes];
|
|
41108
41161
|
}
|
|
41109
41162
|
});
|
|
@@ -41114,16 +41167,16 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41114
41167
|
*/
|
|
41115
41168
|
ShadowSpace.prototype.applyChanges = function (changes) {
|
|
41116
41169
|
return __awaiter(this, void 0, void 0, function () {
|
|
41117
|
-
var changes_1, changes_1_1, change, _a,
|
|
41118
|
-
var
|
|
41170
|
+
var changes_1, changes_1_1, change, _a, e_6_1;
|
|
41171
|
+
var e_6, _b;
|
|
41119
41172
|
return __generator(this, function (_c) {
|
|
41120
41173
|
switch (_c.label) {
|
|
41121
41174
|
case 0:
|
|
41122
|
-
_c.trys.push([0,
|
|
41175
|
+
_c.trys.push([0, 10, 11, 12]);
|
|
41123
41176
|
changes_1 = __values(changes), changes_1_1 = changes_1.next();
|
|
41124
41177
|
_c.label = 1;
|
|
41125
41178
|
case 1:
|
|
41126
|
-
if (!!changes_1_1.done) return [3 /*break*/,
|
|
41179
|
+
if (!!changes_1_1.done) return [3 /*break*/, 9];
|
|
41127
41180
|
change = changes_1_1.value;
|
|
41128
41181
|
_a = change.action;
|
|
41129
41182
|
switch (_a) {
|
|
@@ -41138,26 +41191,27 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41138
41191
|
case 3:
|
|
41139
41192
|
_c.sent();
|
|
41140
41193
|
_c.label = 4;
|
|
41141
|
-
case 4: return [3 /*break*/,
|
|
41194
|
+
case 4: return [3 /*break*/, 8];
|
|
41142
41195
|
case 5: return [4 /*yield*/, this.deleteFile(change.path)];
|
|
41143
41196
|
case 6:
|
|
41144
41197
|
_c.sent();
|
|
41145
|
-
return [3 /*break*/,
|
|
41146
|
-
case 7:
|
|
41198
|
+
return [3 /*break*/, 8];
|
|
41199
|
+
case 7: return [3 /*break*/, 8];
|
|
41200
|
+
case 8:
|
|
41147
41201
|
changes_1_1 = changes_1.next();
|
|
41148
41202
|
return [3 /*break*/, 1];
|
|
41149
|
-
case
|
|
41150
|
-
case 9:
|
|
41151
|
-
e_5_1 = _c.sent();
|
|
41152
|
-
e_5 = { error: e_5_1 };
|
|
41153
|
-
return [3 /*break*/, 11];
|
|
41203
|
+
case 9: return [3 /*break*/, 12];
|
|
41154
41204
|
case 10:
|
|
41205
|
+
e_6_1 = _c.sent();
|
|
41206
|
+
e_6 = { error: e_6_1 };
|
|
41207
|
+
return [3 /*break*/, 12];
|
|
41208
|
+
case 11:
|
|
41155
41209
|
try {
|
|
41156
41210
|
if (changes_1_1 && !changes_1_1.done && (_b = changes_1.return)) _b.call(changes_1);
|
|
41157
41211
|
}
|
|
41158
|
-
finally { if (
|
|
41212
|
+
finally { if (e_6) throw e_6.error; }
|
|
41159
41213
|
return [7 /*endfinally*/];
|
|
41160
|
-
case
|
|
41214
|
+
case 12:
|
|
41161
41215
|
logger("\u5F71\u5B50\u7A7A\u95F4\u5DF2\u5E94\u7528 ".concat(changes.length, " \u4E2A\u53D8\u66F4"));
|
|
41162
41216
|
return [2 /*return*/];
|
|
41163
41217
|
}
|
|
@@ -41205,6 +41259,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41205
41259
|
case 0:
|
|
41206
41260
|
// 检查文件是否在影子空间中
|
|
41207
41261
|
if (!this.hasFile(filePath)) {
|
|
41262
|
+
logger("[ShadowSpace] \u6587\u4EF6\u4E0D\u5728\u5F71\u5B50\u7A7A\u95F4\u4E2D: ".concat(filePath));
|
|
41208
41263
|
return [2 /*return*/, null];
|
|
41209
41264
|
}
|
|
41210
41265
|
_a.label = 1;
|
|
@@ -41262,8 +41317,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41262
41317
|
*/
|
|
41263
41318
|
ShadowSpace.prototype.markAsRemoteModified = function (filePaths) {
|
|
41264
41319
|
return __awaiter(this, void 0, void 0, function () {
|
|
41265
|
-
var now, hasChanges, filePaths_1, filePaths_1_1, filePath, fullPath, stats, content, hash, existingFile, remoteHash, error_5,
|
|
41266
|
-
var
|
|
41320
|
+
var now, hasChanges, filePaths_1, filePaths_1_1, filePath, fullPath, stats, content, hash, existingFile, remoteHash, error_5, e_7_1;
|
|
41321
|
+
var e_7, _a;
|
|
41267
41322
|
return __generator(this, function (_b) {
|
|
41268
41323
|
switch (_b.label) {
|
|
41269
41324
|
case 0:
|
|
@@ -41313,14 +41368,14 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41313
41368
|
return [3 /*break*/, 2];
|
|
41314
41369
|
case 8: return [3 /*break*/, 11];
|
|
41315
41370
|
case 9:
|
|
41316
|
-
|
|
41317
|
-
|
|
41371
|
+
e_7_1 = _b.sent();
|
|
41372
|
+
e_7 = { error: e_7_1 };
|
|
41318
41373
|
return [3 /*break*/, 11];
|
|
41319
41374
|
case 10:
|
|
41320
41375
|
try {
|
|
41321
41376
|
if (filePaths_1_1 && !filePaths_1_1.done && (_a = filePaths_1.return)) _a.call(filePaths_1);
|
|
41322
41377
|
}
|
|
41323
|
-
finally { if (
|
|
41378
|
+
finally { if (e_7) throw e_7.error; }
|
|
41324
41379
|
return [7 /*endfinally*/];
|
|
41325
41380
|
case 11:
|
|
41326
41381
|
if (!hasChanges) return [3 /*break*/, 13];
|
|
@@ -41342,7 +41397,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41342
41397
|
var _a;
|
|
41343
41398
|
return __awaiter(this, void 0, void 0, function () {
|
|
41344
41399
|
var hasChanges, pathsToProcess, pathsToProcess_1, pathsToProcess_1_1, filePath;
|
|
41345
|
-
var
|
|
41400
|
+
var e_8, _b;
|
|
41346
41401
|
return __generator(this, function (_c) {
|
|
41347
41402
|
switch (_c.label) {
|
|
41348
41403
|
case 0:
|
|
@@ -41358,12 +41413,12 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41358
41413
|
}
|
|
41359
41414
|
}
|
|
41360
41415
|
}
|
|
41361
|
-
catch (
|
|
41416
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
41362
41417
|
finally {
|
|
41363
41418
|
try {
|
|
41364
41419
|
if (pathsToProcess_1_1 && !pathsToProcess_1_1.done && (_b = pathsToProcess_1.return)) _b.call(pathsToProcess_1);
|
|
41365
41420
|
}
|
|
41366
|
-
finally { if (
|
|
41421
|
+
finally { if (e_8) throw e_8.error; }
|
|
41367
41422
|
}
|
|
41368
41423
|
if (!hasChanges) return [3 /*break*/, 2];
|
|
41369
41424
|
return [4 /*yield*/, this.saveState()];
|
|
@@ -41383,7 +41438,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41383
41438
|
ShadowSpace.prototype.getSpaceSnapshots = function (_spaceId) {
|
|
41384
41439
|
return __awaiter(this, void 0, void 0, function () {
|
|
41385
41440
|
var snapshots, _a, _b, _c, filePath, shadowEntry, modifyTime, error_6;
|
|
41386
|
-
var
|
|
41441
|
+
var e_9, _d;
|
|
41387
41442
|
return __generator(this, function (_e) {
|
|
41388
41443
|
switch (_e.label) {
|
|
41389
41444
|
case 0:
|
|
@@ -41413,12 +41468,12 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41413
41468
|
});
|
|
41414
41469
|
}
|
|
41415
41470
|
}
|
|
41416
|
-
catch (
|
|
41471
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
41417
41472
|
finally {
|
|
41418
41473
|
try {
|
|
41419
41474
|
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
41420
41475
|
}
|
|
41421
|
-
finally { if (
|
|
41476
|
+
finally { if (e_9) throw e_9.error; }
|
|
41422
41477
|
}
|
|
41423
41478
|
logger("[ShadowSpace] \u83B7\u53D6\u7A7A\u95F4\u5FEB\u7167: ".concat(snapshots.length, " \u4E2A\u6587\u4EF6"));
|
|
41424
41479
|
return [2 /*return*/, snapshots];
|
|
@@ -41457,6 +41512,633 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41457
41512
|
});
|
|
41458
41513
|
});
|
|
41459
41514
|
};
|
|
41515
|
+
/**
|
|
41516
|
+
* 独立同步:获取远端文件快照
|
|
41517
|
+
*/
|
|
41518
|
+
ShadowSpace.prototype.fetchRemoteSnapshot = function () {
|
|
41519
|
+
var _a, _b, _c, _d, _e, _f;
|
|
41520
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
41521
|
+
var requestParams, response, files, snapshot_1, processNode_1, error_8;
|
|
41522
|
+
var _this = this;
|
|
41523
|
+
return __generator(this, function (_g) {
|
|
41524
|
+
switch (_g.label) {
|
|
41525
|
+
case 0:
|
|
41526
|
+
_g.trys.push([0, 2, , 3]);
|
|
41527
|
+
requestParams = {
|
|
41528
|
+
projectId: this.config.projectId,
|
|
41529
|
+
path: '/',
|
|
41530
|
+
options: {
|
|
41531
|
+
recursive: true,
|
|
41532
|
+
includeTypeEntity: false,
|
|
41533
|
+
},
|
|
41534
|
+
};
|
|
41535
|
+
logger('[ShadowSpace] 开始获取远端快照...', requestParams);
|
|
41536
|
+
return [4 /*yield*/, request('/editor/vfs/readdir', requestParams)];
|
|
41537
|
+
case 1:
|
|
41538
|
+
response = _g.sent();
|
|
41539
|
+
// Log response structure for debugging
|
|
41540
|
+
logger('[ShadowSpace] 远端响应数据结构:', {
|
|
41541
|
+
type: typeof response.data,
|
|
41542
|
+
isSuccess: (_a = response.data) === null || _a === void 0 ? void 0 : _a.success,
|
|
41543
|
+
dataType: typeof ((_b = response.data) === null || _b === void 0 ? void 0 : _b.data),
|
|
41544
|
+
isArray: Array.isArray((_c = response.data) === null || _c === void 0 ? void 0 : _c.data),
|
|
41545
|
+
dataKeys: ((_d = response.data) === null || _d === void 0 ? void 0 : _d.data) ? Object.keys(response.data.data) : [],
|
|
41546
|
+
});
|
|
41547
|
+
if (!((_e = response.data) === null || _e === void 0 ? void 0 : _e.success)) {
|
|
41548
|
+
throw new Error(((_f = response.data) === null || _f === void 0 ? void 0 : _f.message) || 'Failed to fetch remote snapshot');
|
|
41549
|
+
}
|
|
41550
|
+
files = response.data.data;
|
|
41551
|
+
if (!Array.isArray(files)) {
|
|
41552
|
+
// If it's an object with a children property (common file system tree structure)
|
|
41553
|
+
if (files && Array.isArray(files.children)) {
|
|
41554
|
+
files = files.children;
|
|
41555
|
+
}
|
|
41556
|
+
else if (files && Array.isArray(files.entries)) {
|
|
41557
|
+
// Fix: Support entries array
|
|
41558
|
+
files = files.entries;
|
|
41559
|
+
}
|
|
41560
|
+
else if (files && typeof files === 'object') {
|
|
41561
|
+
// If it's a map/object structure, try to convert values to array or wrap single object
|
|
41562
|
+
files = [files];
|
|
41563
|
+
}
|
|
41564
|
+
else {
|
|
41565
|
+
logger('[ShadowSpace] 警告: 远端返回的数据不是数组', files);
|
|
41566
|
+
files = [];
|
|
41567
|
+
}
|
|
41568
|
+
}
|
|
41569
|
+
snapshot_1 = [];
|
|
41570
|
+
processNode_1 = function (node) {
|
|
41571
|
+
if (!node)
|
|
41572
|
+
return;
|
|
41573
|
+
// Try to normalize node structure
|
|
41574
|
+
// If node has 'stats', use it. Otherwise, node itself might be stats or metadata.
|
|
41575
|
+
// Based on user provided example:
|
|
41576
|
+
// { "path": "...", "stats": { "type": "file", "contentHash": "..." } }
|
|
41577
|
+
var stats = node.stats || node;
|
|
41578
|
+
var type = stats.type || node.type;
|
|
41579
|
+
var filePath = node.path || stats.path;
|
|
41580
|
+
if (type === 'file') {
|
|
41581
|
+
// 去除开头的 /
|
|
41582
|
+
var relativePath = filePath;
|
|
41583
|
+
if (relativePath.startsWith('/')) {
|
|
41584
|
+
relativePath = relativePath.slice(1);
|
|
41585
|
+
}
|
|
41586
|
+
// 🔥 调试:打印原始路径和标准化后的路径
|
|
41587
|
+
if (relativePath.includes('TicketHistory') ||
|
|
41588
|
+
filePath.includes('TicketHistory')) {
|
|
41589
|
+
logger("[ShadowSpace] Path Normalization: \"".concat(filePath, "\" -> \"").concat(relativePath, "\""));
|
|
41590
|
+
}
|
|
41591
|
+
// 忽略文件
|
|
41592
|
+
if (_this.shouldIgnoreFile(relativePath)) {
|
|
41593
|
+
return;
|
|
41594
|
+
}
|
|
41595
|
+
snapshot_1.push({
|
|
41596
|
+
path: relativePath,
|
|
41597
|
+
hash: stats.contentHash || '',
|
|
41598
|
+
modify: stats.modifyTime || 0,
|
|
41599
|
+
size: stats.size || 0,
|
|
41600
|
+
});
|
|
41601
|
+
}
|
|
41602
|
+
// Handle recursive directory structure if present
|
|
41603
|
+
if (node.children && Array.isArray(node.children)) {
|
|
41604
|
+
node.children.forEach(processNode_1);
|
|
41605
|
+
}
|
|
41606
|
+
};
|
|
41607
|
+
files.forEach(processNode_1);
|
|
41608
|
+
logger("[ShadowSpace] \u83B7\u53D6\u5230 ".concat(snapshot_1.length, " \u4E2A\u8FDC\u7AEF\u6587\u4EF6"));
|
|
41609
|
+
return [2 /*return*/, snapshot_1];
|
|
41610
|
+
case 2:
|
|
41611
|
+
error_8 = _g.sent();
|
|
41612
|
+
console.error('[ShadowSpace] 获取远端快照失败:', error_8);
|
|
41613
|
+
if (error_8.response) {
|
|
41614
|
+
console.error('[ShadowSpace] 远端响应详情:', {
|
|
41615
|
+
status: error_8.response.status,
|
|
41616
|
+
statusText: error_8.response.statusText,
|
|
41617
|
+
data: error_8.response.data,
|
|
41618
|
+
headers: error_8.response.headers,
|
|
41619
|
+
});
|
|
41620
|
+
}
|
|
41621
|
+
throw error_8;
|
|
41622
|
+
case 3: return [2 /*return*/];
|
|
41623
|
+
}
|
|
41624
|
+
});
|
|
41625
|
+
});
|
|
41626
|
+
};
|
|
41627
|
+
/**
|
|
41628
|
+
* 独立同步:下载远端文件
|
|
41629
|
+
*/
|
|
41630
|
+
ShadowSpace.prototype.downloadRemoteFile = function (filePath) {
|
|
41631
|
+
var _a, _b;
|
|
41632
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
41633
|
+
var remotePath, response, error_9;
|
|
41634
|
+
return __generator(this, function (_c) {
|
|
41635
|
+
switch (_c.label) {
|
|
41636
|
+
case 0:
|
|
41637
|
+
_c.trys.push([0, 2, , 3]);
|
|
41638
|
+
remotePath = filePath.startsWith('/') ? filePath : '/' + filePath;
|
|
41639
|
+
return [4 /*yield*/, request('/editor/vfs/read', {
|
|
41640
|
+
projectId: this.config.projectId,
|
|
41641
|
+
path: remotePath,
|
|
41642
|
+
isCodeMode: true,
|
|
41643
|
+
})];
|
|
41644
|
+
case 1:
|
|
41645
|
+
response = _c.sent();
|
|
41646
|
+
if (!((_a = response.data) === null || _a === void 0 ? void 0 : _a.success)) {
|
|
41647
|
+
throw new Error(((_b = response.data) === null || _b === void 0 ? void 0 : _b.message) || "Failed to download file: ".concat(filePath));
|
|
41648
|
+
}
|
|
41649
|
+
return [2 /*return*/, response.data.data.content];
|
|
41650
|
+
case 2:
|
|
41651
|
+
error_9 = _c.sent();
|
|
41652
|
+
console.error("[ShadowSpace] \u4E0B\u8F7D\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_9);
|
|
41653
|
+
throw error_9;
|
|
41654
|
+
case 3: return [2 /*return*/];
|
|
41655
|
+
}
|
|
41656
|
+
});
|
|
41657
|
+
});
|
|
41658
|
+
};
|
|
41659
|
+
/**
|
|
41660
|
+
* 独立同步:上传本地文件
|
|
41661
|
+
*/
|
|
41662
|
+
ShadowSpace.prototype.uploadLocalFile = function (filePath, content) {
|
|
41663
|
+
var _a, _b;
|
|
41664
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
41665
|
+
var remotePath, response, error_10;
|
|
41666
|
+
return __generator(this, function (_c) {
|
|
41667
|
+
switch (_c.label) {
|
|
41668
|
+
case 0:
|
|
41669
|
+
_c.trys.push([0, 2, , 3]);
|
|
41670
|
+
remotePath = filePath.startsWith('/') ? filePath : '/' + filePath;
|
|
41671
|
+
return [4 /*yield*/, request('/editor/vfs/write', {
|
|
41672
|
+
projectId: this.config.projectId,
|
|
41673
|
+
path: remotePath,
|
|
41674
|
+
content: content,
|
|
41675
|
+
options: {
|
|
41676
|
+
writeMode: 'code',
|
|
41677
|
+
skipValidation: true,
|
|
41678
|
+
},
|
|
41679
|
+
})];
|
|
41680
|
+
case 1:
|
|
41681
|
+
response = _c.sent();
|
|
41682
|
+
if (!((_a = response.data) === null || _a === void 0 ? void 0 : _a.success)) {
|
|
41683
|
+
throw new Error(((_b = response.data) === null || _b === void 0 ? void 0 : _b.message) || "Failed to upload file: ".concat(filePath));
|
|
41684
|
+
}
|
|
41685
|
+
return [3 /*break*/, 3];
|
|
41686
|
+
case 2:
|
|
41687
|
+
error_10 = _c.sent();
|
|
41688
|
+
console.error("[ShadowSpace] \u4E0A\u4F20\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_10);
|
|
41689
|
+
throw error_10;
|
|
41690
|
+
case 3: return [2 /*return*/];
|
|
41691
|
+
}
|
|
41692
|
+
});
|
|
41693
|
+
});
|
|
41694
|
+
};
|
|
41695
|
+
/**
|
|
41696
|
+
* 比对快照,生成变更列表
|
|
41697
|
+
* (从 ShadowSpaceCommandHandler 移动而来,核心比对逻辑)
|
|
41698
|
+
*/
|
|
41699
|
+
ShadowSpace.prototype.compareSnapshots = function (remoteSnapshots, localSnapshots) {
|
|
41700
|
+
var e_10, _a, e_11, _b;
|
|
41701
|
+
var changes = [];
|
|
41702
|
+
// 标准化路径工具函数
|
|
41703
|
+
var normalizePath = function (p) {
|
|
41704
|
+
// 统一替换反斜杠为正斜杠
|
|
41705
|
+
var normalized = p.replace(/\\/g, '/');
|
|
41706
|
+
// 去除开头的 ./
|
|
41707
|
+
if (normalized.startsWith('./'))
|
|
41708
|
+
normalized = normalized.substring(2);
|
|
41709
|
+
// 去除开头的 /
|
|
41710
|
+
if (normalized.startsWith('/'))
|
|
41711
|
+
normalized = normalized.substring(1);
|
|
41712
|
+
return normalized;
|
|
41713
|
+
};
|
|
41714
|
+
// 确保输入参数是数组
|
|
41715
|
+
var safeRemoteSnapshots = Array.isArray(remoteSnapshots)
|
|
41716
|
+
? remoteSnapshots
|
|
41717
|
+
: [];
|
|
41718
|
+
var safeLocalSnapshots = Array.isArray(localSnapshots)
|
|
41719
|
+
? localSnapshots
|
|
41720
|
+
: [];
|
|
41721
|
+
// 构建映射表 (强制标准化 key)
|
|
41722
|
+
var remoteMap = new Map(safeRemoteSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
|
|
41723
|
+
var localMap = new Map(safeLocalSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
|
|
41724
|
+
var remoteKeys = Array.from(remoteMap.keys());
|
|
41725
|
+
var localKeys = Array.from(localMap.keys());
|
|
41726
|
+
var remoteKey = remoteKeys.find(function (k) { return k.includes('__afterRequest'); });
|
|
41727
|
+
var localKey = localKeys.find(function (k) { return k.includes('__afterRequest'); });
|
|
41728
|
+
if (remoteKey || localKey) {
|
|
41729
|
+
logger('[ShadowSpace] CharCodes Debug:', {
|
|
41730
|
+
remoteKey: remoteKey,
|
|
41731
|
+
remoteCodes: remoteKey
|
|
41732
|
+
? Array.from(remoteKey).map(function (c) { return c.charCodeAt(0); })
|
|
41733
|
+
: null,
|
|
41734
|
+
localKey: localKey,
|
|
41735
|
+
localCodes: localKey
|
|
41736
|
+
? Array.from(localKey).map(function (c) { return c.charCodeAt(0); })
|
|
41737
|
+
: null,
|
|
41738
|
+
isEqual: remoteKey === localKey,
|
|
41739
|
+
});
|
|
41740
|
+
}
|
|
41741
|
+
logger('[ShadowSpace] 比对文件列表 (Normalized):', {
|
|
41742
|
+
remoteCount: remoteMap.size,
|
|
41743
|
+
localCount: localMap.size,
|
|
41744
|
+
remoteFiles: Array.from(remoteMap.keys()),
|
|
41745
|
+
localFiles: Array.from(localMap.keys()),
|
|
41746
|
+
});
|
|
41747
|
+
// 1. 检测远端的变更(相对于本地)
|
|
41748
|
+
// 遍历远端文件
|
|
41749
|
+
console.log('localMap: ', localMap.keys());
|
|
41750
|
+
var _loop_2 = function (filePath, remoteFile) {
|
|
41751
|
+
var localFile = localMap.get(filePath);
|
|
41752
|
+
if (!localFile) {
|
|
41753
|
+
console.log('filePath: ', filePath, filePath.length, filePath.startsWith(' '));
|
|
41754
|
+
// 本地缺失 -> 需要从远端拉取 (Pull)
|
|
41755
|
+
logger("[ShadowSpace] \u53D1\u73B0\u672C\u5730\u7F3A\u5931: ".concat(filePath, " (Add to Local)"));
|
|
41756
|
+
changes.push({
|
|
41757
|
+
action: 'add',
|
|
41758
|
+
path: filePath,
|
|
41759
|
+
side: 'editor',
|
|
41760
|
+
sourceLabel: 'remote',
|
|
41761
|
+
targetLabel: 'local',
|
|
41762
|
+
editorHash: remoteFile.hash,
|
|
41763
|
+
spaceHash: null,
|
|
41764
|
+
});
|
|
41765
|
+
}
|
|
41766
|
+
else if (remoteFile.hash !== localFile.hash) {
|
|
41767
|
+
// Hash 不同,需要判断谁是最新版本
|
|
41768
|
+
var remoteModify = remoteFile.modify || 0;
|
|
41769
|
+
var localModify = localFile.modify || 0;
|
|
41770
|
+
logger("[ShadowSpace] \u53D1\u73B0\u53D8\u66F4: ".concat(filePath), {
|
|
41771
|
+
remoteHash: remoteFile.hash,
|
|
41772
|
+
localHash: localFile.hash,
|
|
41773
|
+
remoteModify: remoteModify,
|
|
41774
|
+
localModify: localModify,
|
|
41775
|
+
diff: remoteModify - localModify,
|
|
41776
|
+
});
|
|
41777
|
+
// 如果远端哈希与本地记录的"上次远端哈希"不同,说明远端更新了
|
|
41778
|
+
// const remoteChanged = remoteFile.hash !== localFile.remoteHash;
|
|
41779
|
+
// 如果本地哈希与本地记录的"上次远端哈希"不同,说明本地更新了 (注意:localFile.hash 是当前本地hash)
|
|
41780
|
+
// 实际上 localFile.remoteHash 是上次同步时的远端hash
|
|
41781
|
+
// 如果 localFile.hash != localFile.remoteHash,说明本地有修改
|
|
41782
|
+
// 简单策略:基于时间戳 (或者后续基于 remoteHash 追踪)
|
|
41783
|
+
// 这里沿用 Handler 的时间戳逻辑
|
|
41784
|
+
if (remoteModify > localModify) {
|
|
41785
|
+
// 远端更新 -> 拉取
|
|
41786
|
+
changes.push({
|
|
41787
|
+
action: 'modify',
|
|
41788
|
+
path: filePath,
|
|
41789
|
+
side: 'editor',
|
|
41790
|
+
sourceLabel: 'remote',
|
|
41791
|
+
targetLabel: 'local',
|
|
41792
|
+
editorHash: remoteFile.hash,
|
|
41793
|
+
spaceHash: localFile.hash,
|
|
41794
|
+
});
|
|
41795
|
+
}
|
|
41796
|
+
else if (localModify > remoteModify) {
|
|
41797
|
+
// 本地更新 -> 推送
|
|
41798
|
+
changes.push({
|
|
41799
|
+
action: 'modify',
|
|
41800
|
+
path: filePath,
|
|
41801
|
+
side: 'space',
|
|
41802
|
+
sourceLabel: 'local',
|
|
41803
|
+
targetLabel: 'remote',
|
|
41804
|
+
editorHash: remoteFile.hash,
|
|
41805
|
+
spaceHash: localFile.hash,
|
|
41806
|
+
});
|
|
41807
|
+
}
|
|
41808
|
+
else {
|
|
41809
|
+
// 时间戳相同但哈希不同?冲突,默认拉取远端
|
|
41810
|
+
// 只有当两者都没被放入changes时才放入,避免重复
|
|
41811
|
+
var existingChange = changes.find(function (c) { return c.path === filePath; });
|
|
41812
|
+
if (!existingChange) {
|
|
41813
|
+
changes.push({
|
|
41814
|
+
action: 'modify',
|
|
41815
|
+
path: filePath,
|
|
41816
|
+
side: 'editor',
|
|
41817
|
+
sourceLabel: 'remote',
|
|
41818
|
+
targetLabel: 'local',
|
|
41819
|
+
editorHash: remoteFile.hash,
|
|
41820
|
+
spaceHash: localFile.hash,
|
|
41821
|
+
conflict: true,
|
|
41822
|
+
});
|
|
41823
|
+
}
|
|
41824
|
+
}
|
|
41825
|
+
}
|
|
41826
|
+
};
|
|
41827
|
+
try {
|
|
41828
|
+
for (var remoteMap_1 = __values(remoteMap), remoteMap_1_1 = remoteMap_1.next(); !remoteMap_1_1.done; remoteMap_1_1 = remoteMap_1.next()) {
|
|
41829
|
+
var _c = __read(remoteMap_1_1.value, 2), filePath = _c[0], remoteFile = _c[1];
|
|
41830
|
+
_loop_2(filePath, remoteFile);
|
|
41831
|
+
}
|
|
41832
|
+
}
|
|
41833
|
+
catch (e_10_1) { e_10 = { error: e_10_1 }; }
|
|
41834
|
+
finally {
|
|
41835
|
+
try {
|
|
41836
|
+
if (remoteMap_1_1 && !remoteMap_1_1.done && (_a = remoteMap_1.return)) _a.call(remoteMap_1);
|
|
41837
|
+
}
|
|
41838
|
+
finally { if (e_10) throw e_10.error; }
|
|
41839
|
+
}
|
|
41840
|
+
try {
|
|
41841
|
+
// 2. 检测本地的新增/删除 (相对于远端)
|
|
41842
|
+
for (var localMap_1 = __values(localMap), localMap_1_1 = localMap_1.next(); !localMap_1_1.done; localMap_1_1 = localMap_1.next()) {
|
|
41843
|
+
var _d = __read(localMap_1_1.value, 2), filePath = _d[0], localFile = _d[1];
|
|
41844
|
+
var remoteFile = remoteMap.get(filePath);
|
|
41845
|
+
if (remoteFile) {
|
|
41846
|
+
// 远端存在,已经在上面处理过了 (Hash不同或相同)
|
|
41847
|
+
// 除非我们要处理元数据更新等,否则跳过
|
|
41848
|
+
continue;
|
|
41849
|
+
}
|
|
41850
|
+
if (!remoteFile) {
|
|
41851
|
+
// 远端不存在
|
|
41852
|
+
// 如果本地文件有 remoteHash 且不为空,说明之前存在于远端 -> 远端删除了 -> 本地也删除 (Pull)
|
|
41853
|
+
if (localFile.remoteHash) {
|
|
41854
|
+
logger("[ShadowSpace] \u53D1\u73B0\u8FDC\u7AEF\u5220\u9664: ".concat(filePath, " (Delete Local)"));
|
|
41855
|
+
changes.push({
|
|
41856
|
+
action: 'delete',
|
|
41857
|
+
path: filePath,
|
|
41858
|
+
side: 'editor',
|
|
41859
|
+
sourceLabel: 'remote',
|
|
41860
|
+
targetLabel: 'local',
|
|
41861
|
+
editorHash: null,
|
|
41862
|
+
spaceHash: localFile.hash,
|
|
41863
|
+
});
|
|
41864
|
+
}
|
|
41865
|
+
else {
|
|
41866
|
+
// 本地新增 -> 推送到远端 (Push)
|
|
41867
|
+
logger("[ShadowSpace] \u53D1\u73B0\u672C\u5730\u65B0\u589E: ".concat(filePath, " (Push to Remote)"));
|
|
41868
|
+
changes.push({
|
|
41869
|
+
action: 'add',
|
|
41870
|
+
path: filePath,
|
|
41871
|
+
side: 'space',
|
|
41872
|
+
sourceLabel: 'local',
|
|
41873
|
+
targetLabel: 'remote',
|
|
41874
|
+
editorHash: null,
|
|
41875
|
+
spaceHash: localFile.hash,
|
|
41876
|
+
});
|
|
41877
|
+
}
|
|
41878
|
+
}
|
|
41879
|
+
}
|
|
41880
|
+
}
|
|
41881
|
+
catch (e_11_1) { e_11 = { error: e_11_1 }; }
|
|
41882
|
+
finally {
|
|
41883
|
+
try {
|
|
41884
|
+
if (localMap_1_1 && !localMap_1_1.done && (_b = localMap_1.return)) _b.call(localMap_1);
|
|
41885
|
+
}
|
|
41886
|
+
finally { if (e_11) throw e_11.error; }
|
|
41887
|
+
}
|
|
41888
|
+
return changes;
|
|
41889
|
+
};
|
|
41890
|
+
/**
|
|
41891
|
+
* 独立同步:执行完整同步
|
|
41892
|
+
*/
|
|
41893
|
+
ShadowSpace.prototype.syncWithRemote = function (options) {
|
|
41894
|
+
if (options === void 0) { options = {}; }
|
|
41895
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
41896
|
+
var remoteSnapshot, localSnapshot, changes, result, changes_2, changes_2_1, change, content, remoteHash, content, err_1, e_12_1;
|
|
41897
|
+
var e_12, _a;
|
|
41898
|
+
return __generator(this, function (_b) {
|
|
41899
|
+
switch (_b.label) {
|
|
41900
|
+
case 0: return [4 /*yield*/, this.fetchRemoteSnapshot()];
|
|
41901
|
+
case 1:
|
|
41902
|
+
remoteSnapshot = _b.sent();
|
|
41903
|
+
if (!(Object.keys(this.state.files).length === 0)) return [3 /*break*/, 3];
|
|
41904
|
+
return [4 /*yield*/, this.syncLocalState()];
|
|
41905
|
+
case 2:
|
|
41906
|
+
_b.sent();
|
|
41907
|
+
_b.label = 3;
|
|
41908
|
+
case 3: return [4 /*yield*/, this.getSpaceSnapshots()];
|
|
41909
|
+
case 4:
|
|
41910
|
+
localSnapshot = _b.sent();
|
|
41911
|
+
changes = this.compareSnapshots(remoteSnapshot, localSnapshot);
|
|
41912
|
+
result = {
|
|
41913
|
+
changes: changes,
|
|
41914
|
+
summary: {
|
|
41915
|
+
total: changes.length,
|
|
41916
|
+
pull: changes.filter(function (c) { return c.side === 'editor'; }).length,
|
|
41917
|
+
push: changes.filter(function (c) { return c.side === 'space'; }).length,
|
|
41918
|
+
},
|
|
41919
|
+
};
|
|
41920
|
+
if (options.dryRun || !options.autoApply) {
|
|
41921
|
+
return [2 /*return*/, result];
|
|
41922
|
+
}
|
|
41923
|
+
_b.label = 5;
|
|
41924
|
+
case 5:
|
|
41925
|
+
_b.trys.push([5, 22, 23, 24]);
|
|
41926
|
+
changes_2 = __values(changes), changes_2_1 = changes_2.next();
|
|
41927
|
+
_b.label = 6;
|
|
41928
|
+
case 6:
|
|
41929
|
+
if (!!changes_2_1.done) return [3 /*break*/, 21];
|
|
41930
|
+
change = changes_2_1.value;
|
|
41931
|
+
_b.label = 7;
|
|
41932
|
+
case 7:
|
|
41933
|
+
_b.trys.push([7, 19, , 20]);
|
|
41934
|
+
if (!(change.side === 'editor')) return [3 /*break*/, 15];
|
|
41935
|
+
if (!(change.action === 'delete')) return [3 /*break*/, 9];
|
|
41936
|
+
return [4 /*yield*/, this.deleteFile(change.path)];
|
|
41937
|
+
case 8:
|
|
41938
|
+
_b.sent();
|
|
41939
|
+
return [3 /*break*/, 14];
|
|
41940
|
+
case 9: return [4 /*yield*/, this.downloadRemoteFile(change.path)];
|
|
41941
|
+
case 10:
|
|
41942
|
+
content = _b.sent();
|
|
41943
|
+
remoteHash = change.editorHash;
|
|
41944
|
+
if (!remoteHash) return [3 /*break*/, 12];
|
|
41945
|
+
return [4 /*yield*/, this.updateFileFromRemote(change.path, content, remoteHash)];
|
|
41946
|
+
case 11:
|
|
41947
|
+
_b.sent();
|
|
41948
|
+
return [3 /*break*/, 14];
|
|
41949
|
+
case 12:
|
|
41950
|
+
// 如果没有 remoteHash (理论上不应该),回退到普通 update
|
|
41951
|
+
return [4 /*yield*/, this.updateFile(change.path, content)];
|
|
41952
|
+
case 13:
|
|
41953
|
+
// 如果没有 remoteHash (理论上不应该),回退到普通 update
|
|
41954
|
+
_b.sent();
|
|
41955
|
+
_b.label = 14;
|
|
41956
|
+
case 14: return [3 /*break*/, 18];
|
|
41957
|
+
case 15:
|
|
41958
|
+
if (!(change.action === 'add' || change.action === 'modify')) return [3 /*break*/, 18];
|
|
41959
|
+
return [4 /*yield*/, this.getShadowContent(change.path)];
|
|
41960
|
+
case 16:
|
|
41961
|
+
content = _b.sent();
|
|
41962
|
+
if (!content) return [3 /*break*/, 18];
|
|
41963
|
+
return [4 /*yield*/, this.uploadLocalFile(change.path, content)];
|
|
41964
|
+
case 17:
|
|
41965
|
+
_b.sent();
|
|
41966
|
+
// 更新状态
|
|
41967
|
+
if (this.state.files[change.path]) {
|
|
41968
|
+
// Push 成功后,远端 Hash 应该等于本地 Hash
|
|
41969
|
+
this.state.files[change.path].remoteHash =
|
|
41970
|
+
this.state.files[change.path].hash;
|
|
41971
|
+
}
|
|
41972
|
+
_b.label = 18;
|
|
41973
|
+
case 18: return [3 /*break*/, 20];
|
|
41974
|
+
case 19:
|
|
41975
|
+
err_1 = _b.sent();
|
|
41976
|
+
console.error("Failed to apply change for ".concat(change.path), err_1);
|
|
41977
|
+
return [3 /*break*/, 20];
|
|
41978
|
+
case 20:
|
|
41979
|
+
changes_2_1 = changes_2.next();
|
|
41980
|
+
return [3 /*break*/, 6];
|
|
41981
|
+
case 21: return [3 /*break*/, 24];
|
|
41982
|
+
case 22:
|
|
41983
|
+
e_12_1 = _b.sent();
|
|
41984
|
+
e_12 = { error: e_12_1 };
|
|
41985
|
+
return [3 /*break*/, 24];
|
|
41986
|
+
case 23:
|
|
41987
|
+
try {
|
|
41988
|
+
if (changes_2_1 && !changes_2_1.done && (_a = changes_2.return)) _a.call(changes_2);
|
|
41989
|
+
}
|
|
41990
|
+
finally { if (e_12) throw e_12.error; }
|
|
41991
|
+
return [7 /*endfinally*/];
|
|
41992
|
+
case 24: return [4 /*yield*/, this.saveState()];
|
|
41993
|
+
case 25:
|
|
41994
|
+
_b.sent();
|
|
41995
|
+
return [2 /*return*/, result];
|
|
41996
|
+
}
|
|
41997
|
+
});
|
|
41998
|
+
});
|
|
41999
|
+
};
|
|
42000
|
+
/**
|
|
42001
|
+
* 🆕 从远端更新文件(正确维护 remoteHash)
|
|
42002
|
+
*/
|
|
42003
|
+
ShadowSpace.prototype.updateFileFromRemote = function (filePath, content, remoteHash) {
|
|
42004
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
42005
|
+
var localHash, size, now, currentEntry;
|
|
42006
|
+
return __generator(this, function (_a) {
|
|
42007
|
+
switch (_a.label) {
|
|
42008
|
+
case 0:
|
|
42009
|
+
if (this.shouldIgnoreFile(filePath)) {
|
|
42010
|
+
return [2 /*return*/, false];
|
|
42011
|
+
}
|
|
42012
|
+
// 1. 写入本地文件
|
|
42013
|
+
return [4 /*yield*/, this.writeLocalFile(filePath, content)];
|
|
42014
|
+
case 1:
|
|
42015
|
+
// 1. 写入本地文件
|
|
42016
|
+
_a.sent();
|
|
42017
|
+
localHash = this.calculateHash(content);
|
|
42018
|
+
size = Buffer.byteLength(content, 'utf8');
|
|
42019
|
+
now = Date.now();
|
|
42020
|
+
currentEntry = this.state.files[filePath];
|
|
42021
|
+
this.state.files[filePath] = {
|
|
42022
|
+
path: filePath,
|
|
42023
|
+
hash: localHash,
|
|
42024
|
+
remoteHash: remoteHash,
|
|
42025
|
+
size: size,
|
|
42026
|
+
lastSyncTime: now,
|
|
42027
|
+
lastModified: now,
|
|
42028
|
+
version: currentEntry ? currentEntry.version + 1 : 1,
|
|
42029
|
+
mtime: now,
|
|
42030
|
+
remoteModified: false, // 已同步,清除标记
|
|
42031
|
+
};
|
|
42032
|
+
// 更新缓存
|
|
42033
|
+
this.contentCache.set(filePath, content);
|
|
42034
|
+
return [2 /*return*/, true];
|
|
42035
|
+
}
|
|
42036
|
+
});
|
|
42037
|
+
});
|
|
42038
|
+
};
|
|
42039
|
+
// ==================== 🆕 文件监听功能 ====================
|
|
42040
|
+
/**
|
|
42041
|
+
* 启动文件监听
|
|
42042
|
+
*/
|
|
42043
|
+
ShadowSpace.prototype.startWatching = function () {
|
|
42044
|
+
var _this = this;
|
|
42045
|
+
if (this.isWatching) {
|
|
42046
|
+
logger('[ShadowSpace] 文件监听已经在运行中');
|
|
42047
|
+
return;
|
|
42048
|
+
}
|
|
42049
|
+
logger('[ShadowSpace] 启动文件监听...');
|
|
42050
|
+
logger('[ShadowSpace] 监听目录:', this.config.projectRoot);
|
|
42051
|
+
try {
|
|
42052
|
+
// 🔥 使用轮询模式 + ignored 函数过滤
|
|
42053
|
+
this.watcher = chokidar__default["default"].watch(this.config.projectRoot, {
|
|
42054
|
+
ignored: function (filePath) {
|
|
42055
|
+
var relativePath = path__default["default"].relative(_this.config.projectRoot, filePath);
|
|
42056
|
+
// 忽略根目录本身
|
|
42057
|
+
if (!relativePath || relativePath === '.') {
|
|
42058
|
+
return true;
|
|
42059
|
+
}
|
|
42060
|
+
// 使用白名单过滤
|
|
42061
|
+
return _this.shouldIgnoreFile(relativePath);
|
|
42062
|
+
},
|
|
42063
|
+
persistent: true,
|
|
42064
|
+
ignoreInitial: true,
|
|
42065
|
+
usePolling: true,
|
|
42066
|
+
interval: 2000,
|
|
42067
|
+
binaryInterval: 3000,
|
|
42068
|
+
depth: 99,
|
|
42069
|
+
awaitWriteFinish: {
|
|
42070
|
+
stabilityThreshold: 500,
|
|
42071
|
+
pollInterval: 100,
|
|
42072
|
+
},
|
|
42073
|
+
});
|
|
42074
|
+
logger('[ShadowSpace] chokidar.watch 已调用,等待 ready 事件...');
|
|
42075
|
+
}
|
|
42076
|
+
catch (error) {
|
|
42077
|
+
console.error('[ShadowSpace] 创建文件监听器失败:', error);
|
|
42078
|
+
}
|
|
42079
|
+
if (this.watcher) {
|
|
42080
|
+
this.watcher
|
|
42081
|
+
.on('change', function (filePath) {
|
|
42082
|
+
_this.onFileChanged(filePath);
|
|
42083
|
+
})
|
|
42084
|
+
.on('add', function (filePath) {
|
|
42085
|
+
_this.onFileAdded(filePath);
|
|
42086
|
+
})
|
|
42087
|
+
.on('unlink', function (filePath) {
|
|
42088
|
+
_this.onFileDeleted(filePath);
|
|
42089
|
+
})
|
|
42090
|
+
.on('error', function (error) {
|
|
42091
|
+
console.error('[ShadowSpace] 文件监听错误:', error);
|
|
42092
|
+
})
|
|
42093
|
+
.on('ready', function () {
|
|
42094
|
+
_this.isWatching = true;
|
|
42095
|
+
logger('[ShadowSpace] 文件监听已启动,正在监听:', _this.config.projectRoot);
|
|
42096
|
+
logger('[ShadowSpace] 监听配置: 轮询模式 (interval: 2s)');
|
|
42097
|
+
});
|
|
42098
|
+
}
|
|
42099
|
+
};
|
|
42100
|
+
/**
|
|
42101
|
+
* 停止文件监听
|
|
42102
|
+
*/
|
|
42103
|
+
ShadowSpace.prototype.stopWatching = function () {
|
|
42104
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
42105
|
+
return __generator(this, function (_a) {
|
|
42106
|
+
switch (_a.label) {
|
|
42107
|
+
case 0:
|
|
42108
|
+
if (!this.isWatching || !this.watcher) {
|
|
42109
|
+
logger('[ShadowSpace] 文件监听未运行');
|
|
42110
|
+
return [2 /*return*/];
|
|
42111
|
+
}
|
|
42112
|
+
logger('[ShadowSpace] 停止文件监听...');
|
|
42113
|
+
return [4 /*yield*/, this.watcher.close()];
|
|
42114
|
+
case 1:
|
|
42115
|
+
_a.sent();
|
|
42116
|
+
this.watcher = null;
|
|
42117
|
+
this.isWatching = false;
|
|
42118
|
+
logger('[ShadowSpace] 文件监听已停止');
|
|
42119
|
+
return [2 /*return*/];
|
|
42120
|
+
}
|
|
42121
|
+
});
|
|
42122
|
+
});
|
|
42123
|
+
};
|
|
42124
|
+
/**
|
|
42125
|
+
* 添加变更事件监听器
|
|
42126
|
+
*/
|
|
42127
|
+
ShadowSpace.prototype.addChangeListener = function (listener) {
|
|
42128
|
+
this.changeListeners.add(listener);
|
|
42129
|
+
};
|
|
42130
|
+
/**
|
|
42131
|
+
* 移除变更事件监听器
|
|
42132
|
+
*/
|
|
42133
|
+
ShadowSpace.prototype.removeChangeListener = function (listener) {
|
|
42134
|
+
this.changeListeners.delete(listener);
|
|
42135
|
+
};
|
|
42136
|
+
/**
|
|
42137
|
+
* 获取监听状态
|
|
42138
|
+
*/
|
|
42139
|
+
ShadowSpace.prototype.isFileWatching = function () {
|
|
42140
|
+
return this.isWatching;
|
|
42141
|
+
};
|
|
41460
42142
|
// ==================== 私有方法 ====================
|
|
41461
42143
|
/**
|
|
41462
42144
|
* 生成基于路径的唯一空间ID
|
|
@@ -41477,6 +42159,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41477
42159
|
var dirName = path__default["default"].basename(absolutePath);
|
|
41478
42160
|
// 组合生成空间ID: 目录名-路径hash
|
|
41479
42161
|
var spaceId = "".concat(dirName, "-").concat(pathHash);
|
|
42162
|
+
logger("[ShadowSpace] \u751F\u6210\u7A7A\u95F4ID: ".concat(spaceId, " (\u8DEF\u5F84: ").concat(absolutePath, ")"));
|
|
41480
42163
|
return spaceId;
|
|
41481
42164
|
};
|
|
41482
42165
|
/**
|
|
@@ -41484,7 +42167,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41484
42167
|
*/
|
|
41485
42168
|
ShadowSpace.prototype.saveSpaceConfig = function () {
|
|
41486
42169
|
return __awaiter(this, void 0, void 0, function () {
|
|
41487
|
-
var configFile, config,
|
|
42170
|
+
var configFile, config, error_11;
|
|
41488
42171
|
return __generator(this, function (_a) {
|
|
41489
42172
|
switch (_a.label) {
|
|
41490
42173
|
case 0:
|
|
@@ -41506,10 +42189,11 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41506
42189
|
return [4 /*yield*/, fs__default$1["default"].writeFile(configFile, JSON.stringify(config, null, 2))];
|
|
41507
42190
|
case 3:
|
|
41508
42191
|
_a.sent();
|
|
42192
|
+
logger("[ShadowSpace] \u7A7A\u95F4\u914D\u7F6E\u5DF2\u4FDD\u5B58: ".concat(configFile));
|
|
41509
42193
|
return [3 /*break*/, 5];
|
|
41510
42194
|
case 4:
|
|
41511
|
-
|
|
41512
|
-
console.warn('[ShadowSpace] 保存空间配置失败:',
|
|
42195
|
+
error_11 = _a.sent();
|
|
42196
|
+
console.warn('[ShadowSpace] 保存空间配置失败:', error_11);
|
|
41513
42197
|
return [3 /*break*/, 5];
|
|
41514
42198
|
case 5: return [2 /*return*/];
|
|
41515
42199
|
}
|
|
@@ -41521,14 +42205,15 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41521
42205
|
*/
|
|
41522
42206
|
ShadowSpace.prototype.migrateOldStateFiles = function () {
|
|
41523
42207
|
return __awaiter(this, void 0, void 0, function () {
|
|
41524
|
-
var appthenDir, files, oldStateFiles, oldStateFiles_1, oldStateFiles_1_1, oldFile, oldFilePath, oldState, backupFile,
|
|
41525
|
-
var
|
|
42208
|
+
var appthenDir, files, oldStateFiles, oldStateFiles_1, oldStateFiles_1_1, oldFile, oldFilePath, oldState, backupFile, e_13_1, error_12;
|
|
42209
|
+
var e_13, _a;
|
|
41526
42210
|
var _this = this;
|
|
41527
42211
|
return __generator(this, function (_b) {
|
|
41528
42212
|
switch (_b.label) {
|
|
41529
42213
|
case 0:
|
|
41530
42214
|
_b.trys.push([0, 12, , 13]);
|
|
41531
42215
|
appthenDir = path__default["default"].join(this.config.projectRoot, '.appthen');
|
|
42216
|
+
logger("[ShadowSpace] \u68C0\u67E5\u8FC1\u79FB: ".concat(appthenDir));
|
|
41532
42217
|
return [4 /*yield*/, fs__default$1["default"].readdir(appthenDir)];
|
|
41533
42218
|
case 1:
|
|
41534
42219
|
files = _b.sent();
|
|
@@ -41568,25 +42253,26 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41568
42253
|
case 6:
|
|
41569
42254
|
_b.sent();
|
|
41570
42255
|
logger("[ShadowSpace] \u5DF2\u8FC1\u79FB ".concat(Object.keys(this.state.files).length, " \u4E2A\u6587\u4EF6\u5230\u65B0\u7A7A\u95F4 ").concat(this.config.spaceId));
|
|
42256
|
+
logger("[ShadowSpace] \u65E7\u6587\u4EF6\u5DF2\u5907\u4EFD\u4E3A: ".concat(backupFile));
|
|
41571
42257
|
return [3 /*break*/, 8]; // 只迁移第一个匹配的文件
|
|
41572
42258
|
case 7:
|
|
41573
42259
|
oldStateFiles_1_1 = oldStateFiles_1.next();
|
|
41574
42260
|
return [3 /*break*/, 3];
|
|
41575
42261
|
case 8: return [3 /*break*/, 11];
|
|
41576
42262
|
case 9:
|
|
41577
|
-
|
|
41578
|
-
|
|
42263
|
+
e_13_1 = _b.sent();
|
|
42264
|
+
e_13 = { error: e_13_1 };
|
|
41579
42265
|
return [3 /*break*/, 11];
|
|
41580
42266
|
case 10:
|
|
41581
42267
|
try {
|
|
41582
42268
|
if (oldStateFiles_1_1 && !oldStateFiles_1_1.done && (_a = oldStateFiles_1.return)) _a.call(oldStateFiles_1);
|
|
41583
42269
|
}
|
|
41584
|
-
finally { if (
|
|
42270
|
+
finally { if (e_13) throw e_13.error; }
|
|
41585
42271
|
return [7 /*endfinally*/];
|
|
41586
42272
|
case 11: return [3 /*break*/, 13];
|
|
41587
42273
|
case 12:
|
|
41588
|
-
|
|
41589
|
-
console.warn('[ShadowSpace] 迁移旧状态文件失败:',
|
|
42274
|
+
error_12 = _b.sent();
|
|
42275
|
+
console.warn('[ShadowSpace] 迁移旧状态文件失败:', error_12);
|
|
41590
42276
|
return [3 /*break*/, 13];
|
|
41591
42277
|
case 13: return [2 /*return*/];
|
|
41592
42278
|
}
|
|
@@ -41595,7 +42281,7 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41595
42281
|
};
|
|
41596
42282
|
ShadowSpace.prototype.getShadowContent = function (filePath) {
|
|
41597
42283
|
return __awaiter(this, void 0, void 0, function () {
|
|
41598
|
-
var localPath, content,
|
|
42284
|
+
var localPath, content, error_13;
|
|
41599
42285
|
return __generator(this, function (_a) {
|
|
41600
42286
|
switch (_a.label) {
|
|
41601
42287
|
case 0:
|
|
@@ -41613,8 +42299,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41613
42299
|
this.contentCache.set(filePath, content);
|
|
41614
42300
|
return [2 /*return*/, content];
|
|
41615
42301
|
case 3:
|
|
41616
|
-
|
|
41617
|
-
console.warn("\u65E0\u6CD5\u83B7\u53D6\u5F71\u5B50\u5185\u5BB9: ".concat(filePath),
|
|
42302
|
+
error_13 = _a.sent();
|
|
42303
|
+
console.warn("\u65E0\u6CD5\u83B7\u53D6\u5F71\u5B50\u5185\u5BB9: ".concat(filePath), error_13);
|
|
41618
42304
|
return [2 /*return*/, ''];
|
|
41619
42305
|
case 4: return [2 /*return*/];
|
|
41620
42306
|
}
|
|
@@ -41629,11 +42315,13 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41629
42315
|
.digest('hex');
|
|
41630
42316
|
};
|
|
41631
42317
|
ShadowSpace.prototype.generateId = function () {
|
|
41632
|
-
return "change_".concat(Date.now(), "_").concat(Math.random()
|
|
42318
|
+
return "change_".concat(Date.now(), "_").concat(Math.random()
|
|
42319
|
+
.toString(36)
|
|
42320
|
+
.substring(2, 11));
|
|
41633
42321
|
};
|
|
41634
42322
|
ShadowSpace.prototype.shouldIgnoreFile = function (filePath) {
|
|
41635
42323
|
// logger(`[ShadowSpace] shouldIgnoreFile 检查: "${filePath}"`);
|
|
41636
|
-
var
|
|
42324
|
+
var e_14, _a;
|
|
41637
42325
|
// 特殊处理:过滤掉特定的系统文件
|
|
41638
42326
|
var fileName = filePath.split('/').pop() || '';
|
|
41639
42327
|
if (fileName === '.dirty_files.json') {
|
|
@@ -41648,12 +42336,14 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41648
42336
|
// 🔥 目录白名单检查:简化逻辑,允许 src/ 和 docs/ 下的所有文件
|
|
41649
42337
|
var isInSrc = filePath.startsWith('src/');
|
|
41650
42338
|
var isInDocs = filePath.startsWith('docs/');
|
|
41651
|
-
var isRootConfig = filePath.match(/^[
|
|
42339
|
+
var isRootConfig = filePath.match(/^[^/]+\.(json|md|yml|yaml|toml|js|ts|py|go|rs)$/);
|
|
41652
42340
|
if (!isInSrc && !isInDocs && !isRootConfig) {
|
|
42341
|
+
logger("[ShadowSpace] \u6587\u4EF6\u4E0D\u5728\u767D\u540D\u5355\u76EE\u5F55\u4E2D: ".concat(filePath));
|
|
41653
42342
|
return true;
|
|
41654
42343
|
}
|
|
41655
42344
|
// 特殊处理:不忽略其他 .json 文件(即使以 . 开头)
|
|
41656
42345
|
if (filePath.endsWith('.json')) {
|
|
42346
|
+
logger("[ShadowSpace] JSON\u6587\u4EF6\u4E0D\u5FFD\u7565: ".concat(filePath));
|
|
41657
42347
|
return false;
|
|
41658
42348
|
}
|
|
41659
42349
|
try {
|
|
@@ -41666,27 +42356,28 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41666
42356
|
}
|
|
41667
42357
|
}
|
|
41668
42358
|
}
|
|
41669
|
-
catch (
|
|
42359
|
+
catch (e_14_1) { e_14 = { error: e_14_1 }; }
|
|
41670
42360
|
finally {
|
|
41671
42361
|
try {
|
|
41672
42362
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
41673
42363
|
}
|
|
41674
|
-
finally { if (
|
|
42364
|
+
finally { if (e_14) throw e_14.error; }
|
|
41675
42365
|
}
|
|
41676
42366
|
// 检查扩展名白名单
|
|
41677
42367
|
if (this.config.includeExtensions &&
|
|
41678
42368
|
this.config.includeExtensions.length > 0) {
|
|
41679
42369
|
var ext = path__default["default"].extname(filePath).toLowerCase();
|
|
41680
42370
|
if (!this.config.includeExtensions.includes(ext)) {
|
|
42371
|
+
logger("[ShadowSpace] \u6587\u4EF6\u6269\u5C55\u540D\u4E0D\u5728\u767D\u540D\u5355: ".concat(filePath, " -> ").concat(ext));
|
|
41681
42372
|
return true;
|
|
41682
42373
|
}
|
|
41683
42374
|
}
|
|
41684
|
-
|
|
42375
|
+
logger("[ShadowSpace] \u6587\u4EF6\u901A\u8FC7\u5FFD\u7565\u68C0\u67E5: ".concat(filePath));
|
|
41685
42376
|
return false;
|
|
41686
42377
|
};
|
|
41687
42378
|
ShadowSpace.prototype.writeLocalFile = function (filePath, content) {
|
|
41688
42379
|
return __awaiter(this, void 0, void 0, function () {
|
|
41689
|
-
var fullPath,
|
|
42380
|
+
var fullPath, error_14;
|
|
41690
42381
|
return __generator(this, function (_a) {
|
|
41691
42382
|
switch (_a.label) {
|
|
41692
42383
|
case 0:
|
|
@@ -41708,18 +42399,99 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41708
42399
|
_a.sent();
|
|
41709
42400
|
return [3 /*break*/, 5];
|
|
41710
42401
|
case 4:
|
|
41711
|
-
|
|
41712
|
-
console.error("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u5931\u8D25: ".concat(fullPath),
|
|
41713
|
-
throw
|
|
42402
|
+
error_14 = _a.sent();
|
|
42403
|
+
console.error("[ShadowSpace] \u6587\u4EF6\u5199\u5165\u5931\u8D25: ".concat(fullPath), error_14);
|
|
42404
|
+
throw error_14;
|
|
41714
42405
|
case 5: return [2 /*return*/];
|
|
41715
42406
|
}
|
|
41716
42407
|
});
|
|
41717
42408
|
});
|
|
41718
42409
|
};
|
|
42410
|
+
/**
|
|
42411
|
+
* 同步本地文件状态到内存和状态文件
|
|
42412
|
+
* (用于CLI独立运行时刷新状态)
|
|
42413
|
+
*/
|
|
42414
|
+
ShadowSpace.prototype.syncLocalState = function () {
|
|
42415
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
42416
|
+
var localFiles, snapshots, currentPaths, localFiles_2, localFiles_2_1, file, hash, entry, _a, _b, key;
|
|
42417
|
+
var e_15, _c, e_16, _d;
|
|
42418
|
+
return __generator(this, function (_e) {
|
|
42419
|
+
switch (_e.label) {
|
|
42420
|
+
case 0: return [4 /*yield*/, this.loadState()];
|
|
42421
|
+
case 1:
|
|
42422
|
+
_e.sent();
|
|
42423
|
+
return [4 /*yield*/, this.scanLocalFiles()];
|
|
42424
|
+
case 2:
|
|
42425
|
+
localFiles = _e.sent();
|
|
42426
|
+
snapshots = [];
|
|
42427
|
+
currentPaths = new Set();
|
|
42428
|
+
try {
|
|
42429
|
+
for (localFiles_2 = __values(localFiles), localFiles_2_1 = localFiles_2.next(); !localFiles_2_1.done; localFiles_2_1 = localFiles_2.next()) {
|
|
42430
|
+
file = localFiles_2_1.value;
|
|
42431
|
+
currentPaths.add(file.relativePath);
|
|
42432
|
+
hash = this.calculateHash(file.content);
|
|
42433
|
+
// Update state
|
|
42434
|
+
if (!this.state.files[file.relativePath]) {
|
|
42435
|
+
this.state.files[file.relativePath] = {
|
|
42436
|
+
path: file.relativePath,
|
|
42437
|
+
hash: hash,
|
|
42438
|
+
size: file.content.length,
|
|
42439
|
+
lastSyncTime: 0,
|
|
42440
|
+
lastModified: 0,
|
|
42441
|
+
version: 1,
|
|
42442
|
+
mtime: file.mtime,
|
|
42443
|
+
};
|
|
42444
|
+
}
|
|
42445
|
+
else {
|
|
42446
|
+
entry = this.state.files[file.relativePath];
|
|
42447
|
+
if (entry.hash !== hash || entry.mtime !== file.mtime) {
|
|
42448
|
+
entry.hash = hash;
|
|
42449
|
+
entry.mtime = file.mtime;
|
|
42450
|
+
}
|
|
42451
|
+
}
|
|
42452
|
+
snapshots.push({
|
|
42453
|
+
path: file.relativePath,
|
|
42454
|
+
hash: hash,
|
|
42455
|
+
modify: file.mtime,
|
|
42456
|
+
remoteHash: this.state.files[file.relativePath].remoteHash,
|
|
42457
|
+
});
|
|
42458
|
+
}
|
|
42459
|
+
}
|
|
42460
|
+
catch (e_15_1) { e_15 = { error: e_15_1 }; }
|
|
42461
|
+
finally {
|
|
42462
|
+
try {
|
|
42463
|
+
if (localFiles_2_1 && !localFiles_2_1.done && (_c = localFiles_2.return)) _c.call(localFiles_2);
|
|
42464
|
+
}
|
|
42465
|
+
finally { if (e_15) throw e_15.error; }
|
|
42466
|
+
}
|
|
42467
|
+
try {
|
|
42468
|
+
// Remove deleted files from state
|
|
42469
|
+
for (_a = __values(Object.keys(this.state.files)), _b = _a.next(); !_b.done; _b = _a.next()) {
|
|
42470
|
+
key = _b.value;
|
|
42471
|
+
if (!currentPaths.has(key)) {
|
|
42472
|
+
delete this.state.files[key];
|
|
42473
|
+
}
|
|
42474
|
+
}
|
|
42475
|
+
}
|
|
42476
|
+
catch (e_16_1) { e_16 = { error: e_16_1 }; }
|
|
42477
|
+
finally {
|
|
42478
|
+
try {
|
|
42479
|
+
if (_b && !_b.done && (_d = _a.return)) _d.call(_a);
|
|
42480
|
+
}
|
|
42481
|
+
finally { if (e_16) throw e_16.error; }
|
|
42482
|
+
}
|
|
42483
|
+
return [4 /*yield*/, this.saveState()];
|
|
42484
|
+
case 3:
|
|
42485
|
+
_e.sent();
|
|
42486
|
+
return [2 /*return*/, snapshots];
|
|
42487
|
+
}
|
|
42488
|
+
});
|
|
42489
|
+
});
|
|
42490
|
+
};
|
|
41719
42491
|
ShadowSpace.prototype.scanLocalFiles = function () {
|
|
41720
42492
|
return __awaiter(this, void 0, void 0, function () {
|
|
41721
|
-
var files, pattern, options, filePaths, filePaths_2, filePaths_2_1, filePath, fullPath, content, stats,
|
|
41722
|
-
var
|
|
42493
|
+
var files, pattern, options, globPromise, filePaths, filePaths_2, filePaths_2_1, filePath, fullPath, content, stats, error_15, e_17_1;
|
|
42494
|
+
var e_17, _a;
|
|
41723
42495
|
return __generator(this, function (_b) {
|
|
41724
42496
|
switch (_b.label) {
|
|
41725
42497
|
case 0:
|
|
@@ -41730,52 +42502,55 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41730
42502
|
ignore: this.config.ignorePatterns,
|
|
41731
42503
|
nodir: true,
|
|
41732
42504
|
};
|
|
41733
|
-
|
|
41734
|
-
|
|
42505
|
+
globPromise = util$3.promisify(glob__default["default"]);
|
|
42506
|
+
return [4 /*yield*/, globPromise(pattern, options)];
|
|
41735
42507
|
case 1:
|
|
41736
|
-
_b.
|
|
41737
|
-
filePaths_2 = __values(filePaths), filePaths_2_1 = filePaths_2.next();
|
|
42508
|
+
filePaths = _b.sent();
|
|
41738
42509
|
_b.label = 2;
|
|
41739
42510
|
case 2:
|
|
41740
|
-
|
|
41741
|
-
|
|
41742
|
-
if (this.shouldIgnoreFile(filePath))
|
|
41743
|
-
return [3 /*break*/, 7];
|
|
42511
|
+
_b.trys.push([2, 10, 11, 12]);
|
|
42512
|
+
filePaths_2 = __values(filePaths), filePaths_2_1 = filePaths_2.next();
|
|
41744
42513
|
_b.label = 3;
|
|
41745
42514
|
case 3:
|
|
41746
|
-
|
|
42515
|
+
if (!!filePaths_2_1.done) return [3 /*break*/, 9];
|
|
42516
|
+
filePath = filePaths_2_1.value;
|
|
42517
|
+
if (this.shouldIgnoreFile(filePath))
|
|
42518
|
+
return [3 /*break*/, 8];
|
|
42519
|
+
_b.label = 4;
|
|
42520
|
+
case 4:
|
|
42521
|
+
_b.trys.push([4, 7, , 8]);
|
|
41747
42522
|
fullPath = path__default["default"].join(this.config.projectRoot, filePath);
|
|
41748
42523
|
return [4 /*yield*/, fs__default$1["default"].readFile(fullPath, 'utf8')];
|
|
41749
|
-
case
|
|
42524
|
+
case 5:
|
|
41750
42525
|
content = _b.sent();
|
|
41751
42526
|
return [4 /*yield*/, fs__default$1["default"].stat(fullPath)];
|
|
41752
|
-
case
|
|
42527
|
+
case 6:
|
|
41753
42528
|
stats = _b.sent();
|
|
41754
42529
|
files.push({
|
|
41755
42530
|
relativePath: filePath,
|
|
41756
42531
|
content: content,
|
|
41757
42532
|
mtime: stats.mtime.getTime(),
|
|
41758
42533
|
});
|
|
41759
|
-
return [3 /*break*/,
|
|
41760
|
-
case 6:
|
|
41761
|
-
error_12 = _b.sent();
|
|
41762
|
-
console.warn("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_12);
|
|
41763
|
-
return [3 /*break*/, 7];
|
|
42534
|
+
return [3 /*break*/, 8];
|
|
41764
42535
|
case 7:
|
|
42536
|
+
error_15 = _b.sent();
|
|
42537
|
+
console.warn("\u8BFB\u53D6\u6587\u4EF6\u5931\u8D25: ".concat(filePath), error_15);
|
|
42538
|
+
return [3 /*break*/, 8];
|
|
42539
|
+
case 8:
|
|
41765
42540
|
filePaths_2_1 = filePaths_2.next();
|
|
41766
|
-
return [3 /*break*/,
|
|
41767
|
-
case
|
|
41768
|
-
case 9:
|
|
41769
|
-
e_11_1 = _b.sent();
|
|
41770
|
-
e_11 = { error: e_11_1 };
|
|
41771
|
-
return [3 /*break*/, 11];
|
|
42541
|
+
return [3 /*break*/, 3];
|
|
42542
|
+
case 9: return [3 /*break*/, 12];
|
|
41772
42543
|
case 10:
|
|
42544
|
+
e_17_1 = _b.sent();
|
|
42545
|
+
e_17 = { error: e_17_1 };
|
|
42546
|
+
return [3 /*break*/, 12];
|
|
42547
|
+
case 11:
|
|
41773
42548
|
try {
|
|
41774
42549
|
if (filePaths_2_1 && !filePaths_2_1.done && (_a = filePaths_2.return)) _a.call(filePaths_2);
|
|
41775
42550
|
}
|
|
41776
|
-
finally { if (
|
|
42551
|
+
finally { if (e_17) throw e_17.error; }
|
|
41777
42552
|
return [7 /*endfinally*/];
|
|
41778
|
-
case
|
|
42553
|
+
case 12: return [2 /*return*/, files];
|
|
41779
42554
|
}
|
|
41780
42555
|
});
|
|
41781
42556
|
});
|
|
@@ -41817,20 +42592,33 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41817
42592
|
};
|
|
41818
42593
|
ShadowSpace.prototype.loadState = function () {
|
|
41819
42594
|
return __awaiter(this, void 0, void 0, function () {
|
|
41820
|
-
var content;
|
|
42595
|
+
var content, error_16;
|
|
41821
42596
|
return __generator(this, function (_a) {
|
|
41822
42597
|
switch (_a.label) {
|
|
41823
42598
|
case 0:
|
|
41824
|
-
_a.trys.push([0, 2, ,
|
|
42599
|
+
_a.trys.push([0, 2, , 6]);
|
|
41825
42600
|
return [4 /*yield*/, fs__default$1["default"].readFile(this.stateFile, 'utf8')];
|
|
41826
42601
|
case 1:
|
|
41827
42602
|
content = _a.sent();
|
|
41828
42603
|
this.state = __assign(__assign({}, this.state), JSON.parse(content));
|
|
41829
|
-
return [3 /*break*/,
|
|
42604
|
+
return [3 /*break*/, 6];
|
|
41830
42605
|
case 2:
|
|
42606
|
+
error_16 = _a.sent();
|
|
42607
|
+
if (!(error_16.code === 'ENOENT')) return [3 /*break*/, 4];
|
|
42608
|
+
logger('影子空间状态文件不存在,使用默认状态');
|
|
42609
|
+
// Ensure directory exists for future saves
|
|
42610
|
+
// 使用 ensureDir 确保整个路径存在,包括 .appthen
|
|
42611
|
+
return [4 /*yield*/, fs__default$1["default"].ensureDir(path__default["default"].dirname(this.stateFile))];
|
|
42612
|
+
case 3:
|
|
42613
|
+
// Ensure directory exists for future saves
|
|
42614
|
+
// 使用 ensureDir 确保整个路径存在,包括 .appthen
|
|
41831
42615
|
_a.sent();
|
|
41832
|
-
return [3 /*break*/,
|
|
41833
|
-
case
|
|
42616
|
+
return [3 /*break*/, 5];
|
|
42617
|
+
case 4:
|
|
42618
|
+
console.warn('[ShadowSpace] 读取状态文件失败:', error_16);
|
|
42619
|
+
_a.label = 5;
|
|
42620
|
+
case 5: return [3 /*break*/, 6];
|
|
42621
|
+
case 6: return [2 /*return*/];
|
|
41834
42622
|
}
|
|
41835
42623
|
});
|
|
41836
42624
|
});
|
|
@@ -41841,100 +42629,13 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41841
42629
|
var k = 1024;
|
|
41842
42630
|
var sizes = ['B', 'KB', 'MB', 'GB'];
|
|
41843
42631
|
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
41844
|
-
return parseFloat((bytes / Math.pow(k, i)).toFixed(2))
|
|
41845
|
-
};
|
|
41846
|
-
// ==================== 🆕 文件监听功能 ====================
|
|
41847
|
-
/**
|
|
41848
|
-
* 启动文件监听
|
|
41849
|
-
*/
|
|
41850
|
-
ShadowSpace.prototype.startWatching = function () {
|
|
41851
|
-
if (this.isWatching) {
|
|
41852
|
-
return;
|
|
41853
|
-
}
|
|
41854
|
-
logger('[ShadowSpace] 监听目录:', this.config.projectRoot);
|
|
41855
|
-
try {
|
|
41856
|
-
// 🔥 使用轮询模式 + ignored 函数过滤
|
|
41857
|
-
// this.watcher = chokidar.watch(this.config.projectRoot, {
|
|
41858
|
-
// ignored: (filePath: string) => {
|
|
41859
|
-
// const relativePath = path.relative(this.config.projectRoot, filePath);
|
|
41860
|
-
// // 忽略根目录本身
|
|
41861
|
-
// if (!relativePath || relativePath === '.') {
|
|
41862
|
-
// return true;
|
|
41863
|
-
// }
|
|
41864
|
-
// // 使用白名单过滤
|
|
41865
|
-
// return this.shouldIgnoreFile(relativePath);
|
|
41866
|
-
// },
|
|
41867
|
-
// persistent: true,
|
|
41868
|
-
// ignoreInitial: true, // 忽略初始扫描
|
|
41869
|
-
// usePolling: true, // 🔥 macOS 上使用轮询模式(fsevents 在某些环境下不可靠)
|
|
41870
|
-
// interval: 2000, // 轮询间隔 2 秒(降低 CPU 占用)
|
|
41871
|
-
// binaryInterval: 3000, // 二进制文件轮询间隔 3 秒
|
|
41872
|
-
// depth: 99, // 监听所有子目录
|
|
41873
|
-
// awaitWriteFinish: {
|
|
41874
|
-
// stabilityThreshold: 500, // 文件稳定后 500ms 才触发
|
|
41875
|
-
// pollInterval: 100,
|
|
41876
|
-
// },
|
|
41877
|
-
// });
|
|
41878
|
-
logger('[ShadowSpace] chokidar.watch 已调用,等待 ready 事件...');
|
|
41879
|
-
}
|
|
41880
|
-
catch (error) {
|
|
41881
|
-
console.error('[ShadowSpace] 创建文件监听器失败:', error);
|
|
41882
|
-
return;
|
|
41883
|
-
}
|
|
41884
|
-
// this.watcher
|
|
41885
|
-
// .on('change', (filePath: string) => {
|
|
41886
|
-
// this.onFileChanged(filePath);
|
|
41887
|
-
// })
|
|
41888
|
-
// .on('add', (filePath: string) => {
|
|
41889
|
-
// this.onFileAdded(filePath);
|
|
41890
|
-
// })
|
|
41891
|
-
// .on('unlink', (filePath: string) => {
|
|
41892
|
-
// this.onFileDeleted(filePath);
|
|
41893
|
-
// })
|
|
41894
|
-
// .on('error', (error) => {
|
|
41895
|
-
// console.error('[ShadowSpace] 文件监听错误:', error);
|
|
41896
|
-
// })
|
|
41897
|
-
// .on('ready', () => {
|
|
41898
|
-
// this.isWatching = true;
|
|
41899
|
-
// logger(
|
|
41900
|
-
// '[ShadowSpace] 文件监听已启动,正在监听:',
|
|
41901
|
-
// this.config.projectRoot
|
|
41902
|
-
// );
|
|
41903
|
-
// logger('[ShadowSpace] 监听配置: 轮询模式 (interval: 2s)');
|
|
41904
|
-
// });
|
|
41905
|
-
};
|
|
41906
|
-
/**
|
|
41907
|
-
* 停止文件监听
|
|
41908
|
-
*/
|
|
41909
|
-
ShadowSpace.prototype.stopWatching = function () {
|
|
41910
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
41911
|
-
return __generator(this, function (_a) {
|
|
41912
|
-
if (!this.isWatching || !this.watcher) {
|
|
41913
|
-
return [2 /*return*/];
|
|
41914
|
-
}
|
|
41915
|
-
// await this.watcher.close();
|
|
41916
|
-
this.watcher = null;
|
|
41917
|
-
this.isWatching = false;
|
|
41918
|
-
return [2 /*return*/];
|
|
41919
|
-
});
|
|
41920
|
-
});
|
|
41921
|
-
};
|
|
41922
|
-
/**
|
|
41923
|
-
* 添加变更事件监听器
|
|
41924
|
-
*/
|
|
41925
|
-
ShadowSpace.prototype.addChangeListener = function (listener) {
|
|
41926
|
-
this.changeListeners.add(listener);
|
|
41927
|
-
};
|
|
41928
|
-
/**
|
|
41929
|
-
* 移除变更事件监听器
|
|
41930
|
-
*/
|
|
41931
|
-
ShadowSpace.prototype.removeChangeListener = function (listener) {
|
|
41932
|
-
this.changeListeners.delete(listener);
|
|
42632
|
+
return "".concat(parseFloat((bytes / Math.pow(k, i)).toFixed(2)), " ").concat(sizes[i]);
|
|
41933
42633
|
};
|
|
41934
42634
|
/**
|
|
41935
42635
|
* 触发变更事件
|
|
41936
42636
|
*/
|
|
41937
42637
|
ShadowSpace.prototype.emitChangeEvent = function (event) {
|
|
42638
|
+
logger('[ShadowSpace] 触发变更事件:', event);
|
|
41938
42639
|
this.changeListeners.forEach(function (listener) {
|
|
41939
42640
|
try {
|
|
41940
42641
|
listener(event);
|
|
@@ -41949,13 +42650,15 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41949
42650
|
*/
|
|
41950
42651
|
ShadowSpace.prototype.onFileChanged = function (filePath) {
|
|
41951
42652
|
return __awaiter(this, void 0, void 0, function () {
|
|
41952
|
-
var relativePath, shadowEntry, content, hash, stats,
|
|
42653
|
+
var relativePath, shadowEntry, content, hash, stats, error_17;
|
|
41953
42654
|
return __generator(this, function (_a) {
|
|
41954
42655
|
switch (_a.label) {
|
|
41955
42656
|
case 0:
|
|
41956
42657
|
relativePath = path__default["default"].relative(this.config.projectRoot, filePath);
|
|
42658
|
+
logger("[ShadowSpace] \u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u66F4: ".concat(relativePath));
|
|
41957
42659
|
shadowEntry = this.state.files[relativePath];
|
|
41958
42660
|
if (!(shadowEntry === null || shadowEntry === void 0 ? void 0 : shadowEntry.remoteModified)) return [3 /*break*/, 2];
|
|
42661
|
+
logger("[ShadowSpace] \u8DF3\u8FC7\u8FDC\u7A0B\u4FEE\u6539\u7684\u6587\u4EF6: ".concat(relativePath));
|
|
41959
42662
|
shadowEntry.remoteModified = false; // 清除标记
|
|
41960
42663
|
return [4 /*yield*/, this.saveState()];
|
|
41961
42664
|
case 1:
|
|
@@ -41981,8 +42684,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41981
42684
|
});
|
|
41982
42685
|
return [3 /*break*/, 6];
|
|
41983
42686
|
case 5:
|
|
41984
|
-
|
|
41985
|
-
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u53D8\u66F4\u5931\u8D25: ".concat(relativePath),
|
|
42687
|
+
error_17 = _a.sent();
|
|
42688
|
+
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u53D8\u66F4\u5931\u8D25: ".concat(relativePath), error_17);
|
|
41986
42689
|
return [3 /*break*/, 6];
|
|
41987
42690
|
case 6: return [2 /*return*/];
|
|
41988
42691
|
}
|
|
@@ -41994,11 +42697,12 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
41994
42697
|
*/
|
|
41995
42698
|
ShadowSpace.prototype.onFileAdded = function (filePath) {
|
|
41996
42699
|
return __awaiter(this, void 0, void 0, function () {
|
|
41997
|
-
var relativePath, content, hash, stats,
|
|
42700
|
+
var relativePath, content, hash, stats, error_18;
|
|
41998
42701
|
return __generator(this, function (_a) {
|
|
41999
42702
|
switch (_a.label) {
|
|
42000
42703
|
case 0:
|
|
42001
42704
|
relativePath = path__default["default"].relative(this.config.projectRoot, filePath);
|
|
42705
|
+
logger("[ShadowSpace] \u68C0\u6D4B\u5230\u6587\u4EF6\u65B0\u589E: ".concat(relativePath));
|
|
42002
42706
|
_a.label = 1;
|
|
42003
42707
|
case 1:
|
|
42004
42708
|
_a.trys.push([1, 4, , 5]);
|
|
@@ -42020,8 +42724,8 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
42020
42724
|
});
|
|
42021
42725
|
return [3 /*break*/, 5];
|
|
42022
42726
|
case 4:
|
|
42023
|
-
|
|
42024
|
-
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u65B0\u589E\u5931\u8D25: ".concat(relativePath),
|
|
42727
|
+
error_18 = _a.sent();
|
|
42728
|
+
console.error("[ShadowSpace] \u5904\u7406\u6587\u4EF6\u65B0\u589E\u5931\u8D25: ".concat(relativePath), error_18);
|
|
42025
42729
|
return [3 /*break*/, 5];
|
|
42026
42730
|
case 5: return [2 /*return*/];
|
|
42027
42731
|
}
|
|
@@ -42038,8 +42742,10 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
42038
42742
|
switch (_a.label) {
|
|
42039
42743
|
case 0:
|
|
42040
42744
|
relativePath = path__default["default"].relative(this.config.projectRoot, filePath);
|
|
42745
|
+
logger("[ShadowSpace] \u68C0\u6D4B\u5230\u6587\u4EF6\u5220\u9664: ".concat(relativePath));
|
|
42041
42746
|
shadowEntry = this.state.files[relativePath];
|
|
42042
42747
|
if (!(shadowEntry === null || shadowEntry === void 0 ? void 0 : shadowEntry.remoteModified)) return [3 /*break*/, 2];
|
|
42748
|
+
logger("[ShadowSpace] \u8DF3\u8FC7\u8FDC\u7A0B\u5220\u9664\u7684\u6587\u4EF6: ".concat(relativePath));
|
|
42043
42749
|
shadowEntry.remoteModified = false; // 清除标记
|
|
42044
42750
|
return [4 /*yield*/, this.saveState()];
|
|
42045
42751
|
case 1:
|
|
@@ -42058,12 +42764,6 @@ var ShadowSpace = /** @class */ (function () {
|
|
|
42058
42764
|
});
|
|
42059
42765
|
});
|
|
42060
42766
|
};
|
|
42061
|
-
/**
|
|
42062
|
-
* 获取监听状态
|
|
42063
|
-
*/
|
|
42064
|
-
ShadowSpace.prototype.isFileWatching = function () {
|
|
42065
|
-
return this.isWatching;
|
|
42066
|
-
};
|
|
42067
42767
|
return ShadowSpace;
|
|
42068
42768
|
}());
|
|
42069
42769
|
|
|
@@ -42316,22 +43016,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42316
43016
|
changes = _a.sent();
|
|
42317
43017
|
result = {
|
|
42318
43018
|
spaceId: this.shadowSpace.getSpaceInfo().spaceId,
|
|
42319
|
-
changes: changes
|
|
42320
|
-
id: change.id,
|
|
42321
|
-
action: change.action,
|
|
42322
|
-
path: change.path,
|
|
42323
|
-
version: change.version,
|
|
42324
|
-
timestamp: change.timestamp,
|
|
42325
|
-
hasContent: !!change.diff.before || !!change.diff.after,
|
|
42326
|
-
size: {
|
|
42327
|
-
before: change.diff.before
|
|
42328
|
-
? Buffer.byteLength(change.diff.before, 'utf8')
|
|
42329
|
-
: 0,
|
|
42330
|
-
after: change.diff.after
|
|
42331
|
-
? Buffer.byteLength(change.diff.after, 'utf8')
|
|
42332
|
-
: 0,
|
|
42333
|
-
},
|
|
42334
|
-
}); }),
|
|
43019
|
+
changes: changes,
|
|
42335
43020
|
summary: {
|
|
42336
43021
|
total: changes.length,
|
|
42337
43022
|
added: changes.filter(function (c) { return c.action === 'add'; }).length,
|
|
@@ -42853,7 +43538,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42853
43538
|
// `[ShadowSpace] 开始检测变更: 空间=${spaceId}, 编辑器文件=${safeEditorSnapshots.length}个`
|
|
42854
43539
|
// );
|
|
42855
43540
|
// 1. 🔥 先检测本地文件变更,更新影子空间状态,并获取本地变更列表(包括新增文件)
|
|
42856
|
-
console.log(
|
|
43541
|
+
console.log('\n🔍 [DEBUG] 正在检测本地文件变更...');
|
|
42857
43542
|
return [4 /*yield*/, this.shadowSpace.detectChanges()];
|
|
42858
43543
|
case 1:
|
|
42859
43544
|
localChanges = _a.sent();
|
|
@@ -42865,7 +43550,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42865
43550
|
spaceSnapshots = _a.sent();
|
|
42866
43551
|
console.log("\uD83D\uDD0D [DEBUG] getSpaceSnapshots \u8FD4\u56DE\u7ED3\u679C\u7C7B\u578B: ".concat(typeof spaceSnapshots));
|
|
42867
43552
|
console.log("\uD83D\uDD0D [DEBUG] getSpaceSnapshots \u662F\u5426\u4E3A\u6570\u7EC4: ".concat(Array.isArray(spaceSnapshots)));
|
|
42868
|
-
console.log(
|
|
43553
|
+
console.log('🔍 [DEBUG] getSpaceSnapshots 原始结果:', spaceSnapshots);
|
|
42869
43554
|
// 🔍 友好的调试输出
|
|
42870
43555
|
console.log('\n=== 影子空间变更检测调试 ===');
|
|
42871
43556
|
console.log('📁 空间ID:', spaceId);
|
|
@@ -42874,19 +43559,19 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42874
43559
|
spaceInfo = this.shadowSpace.getSpaceInfo();
|
|
42875
43560
|
console.log('\n🏠 影子空间信息:');
|
|
42876
43561
|
console.log(" \uD83D\uDCC2 \u9879\u76EE\u6839\u76EE\u5F55: ".concat(spaceInfo.projectRoot));
|
|
42877
|
-
console.log(
|
|
43562
|
+
// console.log(` 📁 空间目录: ${spaceInfo.spaceRoot}`); // 属性不存在,注释掉
|
|
42878
43563
|
console.log(" \uD83D\uDCCA \u6587\u4EF6\u6570\u91CF: ".concat(spaceInfo.fileCount));
|
|
42879
43564
|
console.log(" \uD83D\uDCE6 \u603B\u5927\u5C0F: ".concat(spaceInfo.totalSize));
|
|
42880
43565
|
console.log(" \uD83C\uDD94 \u7528\u6237ID: ".concat(spaceInfo.userId));
|
|
42881
43566
|
console.log(" \u23F0 \u521B\u5EFA\u65F6\u95F4: ".concat(spaceInfo.createdAt));
|
|
42882
|
-
console.log(" \u23F0 \u66F4\u65B0\u65F6\u95F4: ".concat(spaceInfo.
|
|
43567
|
+
console.log(" \u23F0 \u66F4\u65B0\u65F6\u95F4: ".concat(spaceInfo.lastUpdate)); // 修正属性名
|
|
42883
43568
|
require('path');
|
|
42884
43569
|
fs = require('fs-extra');
|
|
42885
|
-
spaceDir = spaceInfo.
|
|
43570
|
+
spaceDir = spaceInfo.projectRoot;
|
|
42886
43571
|
return [4 /*yield*/, fs.pathExists(spaceDir)];
|
|
42887
43572
|
case 3:
|
|
42888
43573
|
spaceExists = _a.sent();
|
|
42889
|
-
console.log(
|
|
43574
|
+
console.log('\n📁 空间目录检查:');
|
|
42890
43575
|
console.log(" \uD83D\uDCC2 \u8DEF\u5F84: ".concat(spaceDir));
|
|
42891
43576
|
console.log(" \u2705 \u662F\u5426\u5B58\u5728: ".concat(spaceExists));
|
|
42892
43577
|
if (!spaceExists) return [3 /*break*/, 7];
|
|
@@ -42951,7 +43636,7 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
42951
43636
|
}); });
|
|
42952
43637
|
console.log("\uD83D\uDD0D [DEBUG] \u672C\u5730\u65B0\u589E\u6587\u4EF6\u6570\u91CF: ".concat(localAddChanges.length));
|
|
42953
43638
|
if (localAddChanges.length > 0) {
|
|
42954
|
-
console.log(
|
|
43639
|
+
console.log('🔍 [DEBUG] 本地新增文件列表:', localAddChanges.map(function (c) { return c.path; }));
|
|
42955
43640
|
}
|
|
42956
43641
|
changes = __spreadArray(__spreadArray([], __read(snapshotChanges), false), __read(localAddChanges), false);
|
|
42957
43642
|
summary = {
|
|
@@ -43023,18 +43708,29 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
43023
43708
|
ShadowSpaceCommandHandler.prototype.compareSnapshots = function (editorSnapshots, spaceSnapshots) {
|
|
43024
43709
|
var _a, _b;
|
|
43025
43710
|
return __awaiter(this, void 0, void 0, function () {
|
|
43026
|
-
var changes, safeEditorSnapshots, safeSpaceSnapshots, editorMap, spaceMap, editorMap_1, editorMap_1_1, _c, path, editorFile, spaceFile, editorModify, spaceModify, spaceMap_1, spaceMap_1_1, _d, path, spaceFile, editorFile;
|
|
43711
|
+
var changes, normalizePath, safeEditorSnapshots, safeSpaceSnapshots, editorMap, spaceMap, editorMap_1, editorMap_1_1, _c, path, editorFile, spaceFile, editorModify, spaceModify, spaceMap_1, spaceMap_1_1, _d, path, spaceFile, editorFile;
|
|
43027
43712
|
var e_2, _e, e_3, _f;
|
|
43028
43713
|
return __generator(this, function (_g) {
|
|
43029
43714
|
changes = [];
|
|
43715
|
+
normalizePath = function (p) {
|
|
43716
|
+
// 统一替换反斜杠为正斜杠
|
|
43717
|
+
var normalized = p.replace(/\\/g, '/');
|
|
43718
|
+
// 去除开头的 ./
|
|
43719
|
+
if (normalized.startsWith('./'))
|
|
43720
|
+
normalized = normalized.substring(2);
|
|
43721
|
+
// 去除开头的 /
|
|
43722
|
+
if (normalized.startsWith('/'))
|
|
43723
|
+
normalized = normalized.substring(1);
|
|
43724
|
+
return normalized;
|
|
43725
|
+
};
|
|
43030
43726
|
safeEditorSnapshots = Array.isArray(editorSnapshots)
|
|
43031
43727
|
? editorSnapshots
|
|
43032
43728
|
: [];
|
|
43033
43729
|
safeSpaceSnapshots = Array.isArray(spaceSnapshots)
|
|
43034
43730
|
? spaceSnapshots
|
|
43035
43731
|
: [];
|
|
43036
|
-
editorMap = new Map(safeEditorSnapshots.map(function (f) { return [f.path, f]; }));
|
|
43037
|
-
spaceMap = new Map(safeSpaceSnapshots.map(function (f) { return [f.path, f]; }));
|
|
43732
|
+
editorMap = new Map(safeEditorSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
|
|
43733
|
+
spaceMap = new Map(safeSpaceSnapshots.map(function (f) { return [normalizePath(f.path), f]; }));
|
|
43038
43734
|
try {
|
|
43039
43735
|
// 检测编辑器的变更(新增、修改)
|
|
43040
43736
|
for (editorMap_1 = __values(editorMap), editorMap_1_1 = editorMap_1.next(); !editorMap_1_1.done; editorMap_1_1 = editorMap_1.next()) {
|
|
@@ -43042,6 +43738,10 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
43042
43738
|
spaceFile = spaceMap.get(path);
|
|
43043
43739
|
if (!spaceFile) {
|
|
43044
43740
|
// 编辑器新增的文件 → 推送到空间
|
|
43741
|
+
// 🔥 调试:打印路径标准化情况
|
|
43742
|
+
if (path.includes('TicketHistory')) {
|
|
43743
|
+
console.log("[ShadowSpace] \u68C0\u6D4B\u5230\u7F16\u8F91\u5668\u65B0\u589E: \"".concat(path, "\" (Original: \"").concat(editorFile.path, "\")"));
|
|
43744
|
+
}
|
|
43045
43745
|
changes.push({
|
|
43046
43746
|
action: 'add',
|
|
43047
43747
|
path: path,
|
|
@@ -43065,8 +43765,8 @@ var ShadowSpaceCommandHandler = /** @class */ (function () {
|
|
|
43065
43765
|
});
|
|
43066
43766
|
// 🔥 关键逻辑:根据时间戳判断方向
|
|
43067
43767
|
if (editorModify > spaceModify) {
|
|
43068
|
-
// 编辑器更新 → 推送到空间
|
|
43069
|
-
console.log("[ShadowSpace] \
|
|
43768
|
+
// 编辑器更新 → 推送到空间 (Remote -> Local) => Pull
|
|
43769
|
+
console.log("[ShadowSpace] \u2B07\uFE0F \u8FDC\u7AEF\u66F4\u65B0 (\u9700\u62C9\u53D6): ".concat(path));
|
|
43070
43770
|
changes.push({
|
|
43071
43771
|
action: 'modify',
|
|
43072
43772
|
path: path,
|
|
@@ -50082,6 +50782,146 @@ function getToolName(tool) {
|
|
|
50082
50782
|
return toolChoice ? toolChoice.name : tool;
|
|
50083
50783
|
}
|
|
50084
50784
|
|
|
50785
|
+
function startShadowSync(options) {
|
|
50786
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
50787
|
+
var userId, config, shadowSpace, result, changes, changes_1, changes_1_1, change, action, filePath, side, direction, content, remoteHash, content, err_1, e_1_1, error_1;
|
|
50788
|
+
var e_1, _a;
|
|
50789
|
+
return __generator(this, function (_b) {
|
|
50790
|
+
switch (_b.label) {
|
|
50791
|
+
case 0:
|
|
50792
|
+
// Set auth token globally for request utils
|
|
50793
|
+
updateAuthToken(options.authToken);
|
|
50794
|
+
userId = options.userId || 'unknown-user';
|
|
50795
|
+
config = {
|
|
50796
|
+
projectRoot: options.cwd ? path__default["default"].resolve(options.cwd) : process.cwd(),
|
|
50797
|
+
projectId: options.projectId,
|
|
50798
|
+
userId: userId,
|
|
50799
|
+
spaceId: options.spaceId || 'default',
|
|
50800
|
+
};
|
|
50801
|
+
shadowSpace = new ShadowSpace(config);
|
|
50802
|
+
if (options.verbose) {
|
|
50803
|
+
console.log('Starting shadow sync...');
|
|
50804
|
+
console.log("Project ID: ".concat(config.projectId));
|
|
50805
|
+
console.log("Space ID: ".concat(config.spaceId));
|
|
50806
|
+
console.log("User ID: ".concat(config.userId));
|
|
50807
|
+
}
|
|
50808
|
+
_b.label = 1;
|
|
50809
|
+
case 1:
|
|
50810
|
+
_b.trys.push([1, 26, , 27]);
|
|
50811
|
+
// 使用抽象后的通用同步逻辑
|
|
50812
|
+
// 调用 syncWithRemote({ dryRun: true }) 获取变更
|
|
50813
|
+
// 然后复用 ShadowSpace 的公共方法进行处理
|
|
50814
|
+
console.log('Checking for changes...');
|
|
50815
|
+
return [4 /*yield*/, shadowSpace.syncWithRemote({ dryRun: true })];
|
|
50816
|
+
case 2:
|
|
50817
|
+
result = _b.sent();
|
|
50818
|
+
changes = result.changes;
|
|
50819
|
+
if (!(changes.length === 0)) return [3 /*break*/, 3];
|
|
50820
|
+
console.log('Everything is up to date.');
|
|
50821
|
+
return [3 /*break*/, 25];
|
|
50822
|
+
case 3:
|
|
50823
|
+
console.log("Found ".concat(changes.length, " changes."));
|
|
50824
|
+
_b.label = 4;
|
|
50825
|
+
case 4:
|
|
50826
|
+
_b.trys.push([4, 21, 22, 23]);
|
|
50827
|
+
changes_1 = __values(changes), changes_1_1 = changes_1.next();
|
|
50828
|
+
_b.label = 5;
|
|
50829
|
+
case 5:
|
|
50830
|
+
if (!!changes_1_1.done) return [3 /*break*/, 20];
|
|
50831
|
+
change = changes_1_1.value;
|
|
50832
|
+
action = change.action, filePath = change.path, side = change.side;
|
|
50833
|
+
direction = side === 'editor' ? 'Remote->Local (Pull)' : 'Local->Remote (Push)';
|
|
50834
|
+
console.log("Processing ".concat(action, " ").concat(filePath, " (").concat(direction, ")..."));
|
|
50835
|
+
_b.label = 6;
|
|
50836
|
+
case 6:
|
|
50837
|
+
_b.trys.push([6, 18, , 19]);
|
|
50838
|
+
if (!(side === 'editor')) return [3 /*break*/, 14];
|
|
50839
|
+
if (!(action === 'delete')) return [3 /*break*/, 8];
|
|
50840
|
+
return [4 /*yield*/, shadowSpace.deleteFile(filePath)];
|
|
50841
|
+
case 7:
|
|
50842
|
+
_b.sent();
|
|
50843
|
+
console.log("Deleted local file: ".concat(filePath));
|
|
50844
|
+
return [3 /*break*/, 13];
|
|
50845
|
+
case 8: return [4 /*yield*/, shadowSpace.downloadRemoteFile(filePath)];
|
|
50846
|
+
case 9:
|
|
50847
|
+
content = _b.sent();
|
|
50848
|
+
remoteHash = change.editorHash;
|
|
50849
|
+
if (!remoteHash) return [3 /*break*/, 11];
|
|
50850
|
+
return [4 /*yield*/, shadowSpace.updateFileFromRemote(filePath, content, remoteHash)];
|
|
50851
|
+
case 10:
|
|
50852
|
+
_b.sent();
|
|
50853
|
+
console.log("Updated local file: ".concat(filePath, " (with remoteHash)"));
|
|
50854
|
+
return [3 /*break*/, 13];
|
|
50855
|
+
case 11: return [4 /*yield*/, shadowSpace.updateFile(filePath, content)];
|
|
50856
|
+
case 12:
|
|
50857
|
+
_b.sent();
|
|
50858
|
+
console.log("Updated local file: ".concat(filePath));
|
|
50859
|
+
_b.label = 13;
|
|
50860
|
+
case 13: return [3 /*break*/, 17];
|
|
50861
|
+
case 14:
|
|
50862
|
+
if (!(side === 'space')) return [3 /*break*/, 17];
|
|
50863
|
+
if (!(action === 'delete')) return [3 /*break*/, 15];
|
|
50864
|
+
console.warn("Skipping remote delete for: ".concat(filePath, " (Not supported)"));
|
|
50865
|
+
return [3 /*break*/, 17];
|
|
50866
|
+
case 15: return [4 /*yield*/, shadowSpace.getShadowContent(filePath)];
|
|
50867
|
+
case 16:
|
|
50868
|
+
content = _b.sent();
|
|
50869
|
+
if (content !== null) {
|
|
50870
|
+
// DryRun for Push
|
|
50871
|
+
console.log("[DryRun] Would upload remote file: ".concat(filePath));
|
|
50872
|
+
// 注意:在 DryRun 模式下,我们不能更新 remoteHash,因为没有真实上传,
|
|
50873
|
+
// 远端的 Hash 依然是旧的。如果现在更新了 remoteHash,下次比对就会出错。
|
|
50874
|
+
// 所以这里什么都不做。
|
|
50875
|
+
}
|
|
50876
|
+
else {
|
|
50877
|
+
console.error("Failed to read local content for: ".concat(filePath));
|
|
50878
|
+
}
|
|
50879
|
+
_b.label = 17;
|
|
50880
|
+
case 17: return [3 /*break*/, 19];
|
|
50881
|
+
case 18:
|
|
50882
|
+
err_1 = _b.sent();
|
|
50883
|
+
console.error("Failed to process ".concat(filePath, ":"), err_1);
|
|
50884
|
+
return [3 /*break*/, 19];
|
|
50885
|
+
case 19:
|
|
50886
|
+
changes_1_1 = changes_1.next();
|
|
50887
|
+
return [3 /*break*/, 5];
|
|
50888
|
+
case 20: return [3 /*break*/, 23];
|
|
50889
|
+
case 21:
|
|
50890
|
+
e_1_1 = _b.sent();
|
|
50891
|
+
e_1 = { error: e_1_1 };
|
|
50892
|
+
return [3 /*break*/, 23];
|
|
50893
|
+
case 22:
|
|
50894
|
+
try {
|
|
50895
|
+
if (changes_1_1 && !changes_1_1.done && (_a = changes_1.return)) _a.call(changes_1);
|
|
50896
|
+
}
|
|
50897
|
+
finally { if (e_1) throw e_1.error; }
|
|
50898
|
+
return [7 /*endfinally*/];
|
|
50899
|
+
case 23:
|
|
50900
|
+
// Save state after sync
|
|
50901
|
+
return [4 /*yield*/, shadowSpace.saveState()];
|
|
50902
|
+
case 24:
|
|
50903
|
+
// Save state after sync
|
|
50904
|
+
_b.sent();
|
|
50905
|
+
_b.label = 25;
|
|
50906
|
+
case 25: return [3 /*break*/, 27];
|
|
50907
|
+
case 26:
|
|
50908
|
+
error_1 = _b.sent();
|
|
50909
|
+
console.error('Shadow sync failed:', error_1);
|
|
50910
|
+
process.exit(1);
|
|
50911
|
+
return [3 /*break*/, 27];
|
|
50912
|
+
case 27:
|
|
50913
|
+
if (options.watch) {
|
|
50914
|
+
shadowSpace.startWatching();
|
|
50915
|
+
console.log('Watching for file changes...');
|
|
50916
|
+
// Keep process alive
|
|
50917
|
+
return [2 /*return*/, new Promise(function () { })];
|
|
50918
|
+
}
|
|
50919
|
+
return [2 /*return*/];
|
|
50920
|
+
}
|
|
50921
|
+
});
|
|
50922
|
+
});
|
|
50923
|
+
}
|
|
50924
|
+
|
|
50085
50925
|
exports.ShadowSpace = ShadowSpace;
|
|
50086
50926
|
exports.ShadowSpaceDebugger = ShadowSpaceDebugger;
|
|
50087
50927
|
exports.TSXComplianceChecker = TSXComplianceChecker;
|
|
@@ -50106,6 +50946,7 @@ exports.releaseMaterial = releaseMaterial;
|
|
|
50106
50946
|
exports.run = run;
|
|
50107
50947
|
exports.startConnecting = startConnecting;
|
|
50108
50948
|
exports.startProxy = startProxy;
|
|
50949
|
+
exports.startShadowSync = startShadowSync;
|
|
50109
50950
|
exports.startWatching = startWatching;
|
|
50110
50951
|
exports.stopConnecting = stopConnecting;
|
|
50111
50952
|
exports.stopProxy = stopProxy;
|