ide-assi 0.384.0 → 0.387.0

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.
@@ -234777,7 +234777,7 @@ function requireDiffMatchPatch () {
234777
234777
  var diffMatchPatchExports = requireDiffMatchPatch();
234778
234778
 
234779
234779
  // Diff 데코레이션을 위한 StateField 정의 (변동 없음)
234780
- StateField.define({
234780
+ const asisDiffDecorations = StateField.define({
234781
234781
  create() { return Decoration.none; },
234782
234782
  update(decorations, tr) {
234783
234783
  return tr.effects.reduce((currentDecos, effect) => {
@@ -234790,7 +234790,7 @@ StateField.define({
234790
234790
  provide: f => EditorView.decorations.from(f)
234791
234791
  });
234792
234792
 
234793
- StateField.define({
234793
+ const tobeDiffDecorations = StateField.define({
234794
234794
  create() { return Decoration.none; },
234795
234795
  update(decorations, tr) {
234796
234796
  return tr.effects.reduce((currentDecos, effect) => {
@@ -235231,7 +235231,7 @@ export default DocManager;
235231
235231
  javascript(),
235232
235232
  EditorState.readOnly.of(true),
235233
235233
  this.#languageCompartment.of(javascript()),
235234
- //asisDiffDecorations,
235234
+ asisDiffDecorations,
235235
235235
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
235236
235236
  EditorView.updateListener.of((update) => {
235237
235237
  if (update.view.contentDOM.firstChild && !update.view._initialAsisContentLoaded) {
@@ -235253,7 +235253,7 @@ export default DocManager;
235253
235253
  javascript(),
235254
235254
  EditorState.readOnly.of(true),
235255
235255
  this.#languageCompartment.of(javascript()),
235256
- //tobeDiffDecorations,
235256
+ tobeDiffDecorations,
235257
235257
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
235258
235258
  EditorView.updateListener.of((update) => {
235259
235259
  if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
@@ -235304,20 +235304,19 @@ export default DocManager;
235304
235304
  this.#tobeEditorView.scrollDOM.addEventListener('scroll', this._tobeScrollHandler);
235305
235305
  };
235306
235306
 
235307
+ // IdeDiff 클래스 내부
235307
235308
  #applyDiffDecorations = (asisSrc, tobeSrc) => {
235308
235309
  const dmp = new diffMatchPatchExports.diff_match_patch();
235309
235310
  const diffs = dmp.diff_main(asisSrc, tobeSrc);
235310
235311
  dmp.diff_cleanupSemantic(diffs);
235311
235312
 
235312
235313
  const asisLineDecos = [];
235313
- const asisMarkDecos = [];
235314
235314
  const tobeLineDecos = [];
235315
- const tobeMarkDecos = [];
235316
235315
 
235317
235316
  let asisCursor = 0;
235318
235317
  let tobeCursor = 0;
235319
235318
 
235320
- // ⭐️ 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
235319
+ // 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
235321
235320
  // 이 Doc 객체를 사용하여 lineAt()을 호출합니다.
235322
235321
  const asisDoc = Text.of(asisSrc.split('\n'));
235323
235322
  const tobeDoc = Text.of(tobeSrc.split('\n'));
@@ -235327,16 +235326,10 @@ export default DocManager;
235327
235326
 
235328
235327
  switch (op) {
235329
235328
  case diffMatchPatchExports.diff_match_patch.DIFF_INSERT: // Added text
235330
- /**
235331
- tobeMarkDecos.push({
235332
- from: tobeCursor,
235333
- to: tobeCursor + len,
235334
- deco: Decoration.mark({ class: "cm-inserted-inline" })
235335
- }); */
235336
-
235337
235329
  let currentTobeLineOffset = tobeCursor;
235338
235330
  const tobeLines = text.split('\n');
235339
235331
  for (let i = 0; i < tobeLines.length; i++) {
235332
+ // 줄의 시작 오프셋이 tobeDoc의 길이를 넘지 않는지 확인
235340
235333
  if (currentTobeLineOffset < tobeDoc.length) {
235341
235334
  const line = tobeDoc.lineAt(currentTobeLineOffset);
235342
235335
  tobeLineDecos.push({
@@ -235345,26 +235338,21 @@ export default DocManager;
235345
235338
  deco: Decoration.line({ class: "cm-inserted-line-bg" })
235346
235339
  });
235347
235340
  }
235341
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
235348
235342
  currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
235343
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
235349
235344
  if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
235350
235345
  break;
235351
235346
  }
235352
235347
  }
235353
-
235354
235348
  tobeCursor += len;
235355
235349
  break;
235356
235350
 
235357
235351
  case diffMatchPatchExports.diff_match_patch.DIFF_DELETE: // Deleted text
235358
- /**
235359
- asisMarkDecos.push({
235360
- from: asisCursor,
235361
- to: asisCursor + len,
235362
- deco: Decoration.mark({ class: "cm-deleted-inline" })
235363
- }); */
235364
-
235365
235352
  let currentAsisLineOffset = asisCursor;
235366
235353
  const asisLines = text.split('\n');
235367
235354
  for (let i = 0; i < asisLines.length; i++) {
235355
+ // 줄의 시작 오프셋이 asisDoc의 길이를 넘지 않는지 확인
235368
235356
  if (currentAsisLineOffset < asisDoc.length) {
235369
235357
  const line = asisDoc.lineAt(currentAsisLineOffset);
235370
235358
  asisLineDecos.push({
@@ -235373,12 +235361,13 @@ export default DocManager;
235373
235361
  deco: Decoration.line({ class: "cm-deleted-line-bg" })
235374
235362
  });
235375
235363
  }
235364
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
235376
235365
  currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
235366
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
235377
235367
  if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
235378
235368
  break;
235379
235369
  }
235380
235370
  }
235381
-
235382
235371
  asisCursor += len;
235383
235372
  break;
235384
235373
 
@@ -235389,34 +235378,22 @@ export default DocManager;
235389
235378
  }
235390
235379
  }
235391
235380
 
235381
+ // 데코레이션 중복 및 겹침 방지를 위해 정렬
235392
235382
  asisLineDecos.sort((a, b) => a.from - b.from);
235393
- asisMarkDecos.sort((a, b) => a.from - b.from);
235394
235383
  tobeLineDecos.sort((a, b) => a.from - b.from);
235395
- tobeMarkDecos.sort((a, b) => a.from - b.from);
235396
235384
 
235385
+ // 라인 데코레이션 빌더 생성
235397
235386
  const asisLineBuilder = new RangeSetBuilder();
235398
235387
  for (const { from, to, deco } of asisLineDecos) {
235399
235388
  asisLineBuilder.add(from, to, deco);
235400
235389
  }
235401
- const asisMarkBuilder = new RangeSetBuilder();
235402
- for (const { from, to, deco } of asisMarkDecos) {
235403
- asisMarkBuilder.add(from, to, deco);
235404
- }
235405
- const finalAsisDecorations = asisLineBuilder.finish().update({
235406
- add: asisMarkBuilder.finish().children
235407
- });
235390
+ const finalAsisDecorations = asisLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
235408
235391
 
235409
235392
  const tobeLineBuilder = new RangeSetBuilder();
235410
235393
  for (const { from, to, deco } of tobeLineDecos) {
235411
235394
  tobeLineBuilder.add(from, to, deco);
235412
235395
  }
235413
- const tobeMarkBuilder = new RangeSetBuilder();
235414
- for (const { from, to, deco } of tobeMarkDecos) {
235415
- tobeMarkBuilder.add(from, to, deco);
235416
- }
235417
- const finalTobeDecorations = tobeLineBuilder.finish().update({
235418
- add: tobeMarkBuilder.finish().children
235419
- });
235396
+ const finalTobeDecorations = tobeLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
235420
235397
 
235421
235398
  return {
235422
235399
  asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
@@ -235442,7 +235419,7 @@ export default DocManager;
235442
235419
  }
235443
235420
 
235444
235421
  // 데코레이션 효과는 미리 계산해 둡니다.
235445
- //const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
235422
+ const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
235446
235423
 
235447
235424
  // 1단계: 텍스트 내용 변경과 언어 확장을 먼저 디스패치합니다.
235448
235425
  // 'to' 값을 현재 문서 길이 전체로 지정하여 정확한 교체를 보장합니다.
@@ -235460,7 +235437,6 @@ export default DocManager;
235460
235437
  ]
235461
235438
  });
235462
235439
 
235463
- /**
235464
235440
  // ⭐️ 2단계: 텍스트 및 언어 변경이 완전히 적용되고 뷰가 안정화될 시간을 줍니다.
235465
235441
  // 다음 프레임에서 데코레이션 효과만 별도로 디스패치합니다.
235466
235442
  requestAnimationFrame(() => {
@@ -235479,7 +235455,7 @@ export default DocManager;
235479
235455
  // this.#asisEditorView.scrollDOM.scrollTop = 0;
235480
235456
  // this.#tobeEditorView.scrollDOM.scrollTop = 0;
235481
235457
  });
235482
- }); */
235458
+ });
235483
235459
  };
235484
235460
 
235485
235461
  disconnectedCallback() {
@@ -234773,7 +234773,7 @@ function requireDiffMatchPatch () {
234773
234773
  var diffMatchPatchExports = requireDiffMatchPatch();
234774
234774
 
234775
234775
  // Diff 데코레이션을 위한 StateField 정의 (변동 없음)
234776
- StateField.define({
234776
+ const asisDiffDecorations = StateField.define({
234777
234777
  create() { return Decoration.none; },
234778
234778
  update(decorations, tr) {
234779
234779
  return tr.effects.reduce((currentDecos, effect) => {
@@ -234786,7 +234786,7 @@ StateField.define({
234786
234786
  provide: f => EditorView.decorations.from(f)
234787
234787
  });
234788
234788
 
234789
- StateField.define({
234789
+ const tobeDiffDecorations = StateField.define({
234790
234790
  create() { return Decoration.none; },
234791
234791
  update(decorations, tr) {
234792
234792
  return tr.effects.reduce((currentDecos, effect) => {
@@ -235227,7 +235227,7 @@ export default DocManager;
235227
235227
  javascript(),
235228
235228
  EditorState.readOnly.of(true),
235229
235229
  this.#languageCompartment.of(javascript()),
235230
- //asisDiffDecorations,
235230
+ asisDiffDecorations,
235231
235231
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
235232
235232
  EditorView.updateListener.of((update) => {
235233
235233
  if (update.view.contentDOM.firstChild && !update.view._initialAsisContentLoaded) {
@@ -235249,7 +235249,7 @@ export default DocManager;
235249
235249
  javascript(),
235250
235250
  EditorState.readOnly.of(true),
235251
235251
  this.#languageCompartment.of(javascript()),
235252
- //tobeDiffDecorations,
235252
+ tobeDiffDecorations,
235253
235253
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
235254
235254
  EditorView.updateListener.of((update) => {
235255
235255
  if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
@@ -235300,20 +235300,19 @@ export default DocManager;
235300
235300
  this.#tobeEditorView.scrollDOM.addEventListener('scroll', this._tobeScrollHandler);
235301
235301
  };
235302
235302
 
235303
+ // IdeDiff 클래스 내부
235303
235304
  #applyDiffDecorations = (asisSrc, tobeSrc) => {
235304
235305
  const dmp = new diffMatchPatchExports.diff_match_patch();
235305
235306
  const diffs = dmp.diff_main(asisSrc, tobeSrc);
235306
235307
  dmp.diff_cleanupSemantic(diffs);
235307
235308
 
235308
235309
  const asisLineDecos = [];
235309
- const asisMarkDecos = [];
235310
235310
  const tobeLineDecos = [];
235311
- const tobeMarkDecos = [];
235312
235311
 
235313
235312
  let asisCursor = 0;
235314
235313
  let tobeCursor = 0;
235315
235314
 
235316
- // ⭐️ 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
235315
+ // 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
235317
235316
  // 이 Doc 객체를 사용하여 lineAt()을 호출합니다.
235318
235317
  const asisDoc = Text.of(asisSrc.split('\n'));
235319
235318
  const tobeDoc = Text.of(tobeSrc.split('\n'));
@@ -235323,16 +235322,10 @@ export default DocManager;
235323
235322
 
235324
235323
  switch (op) {
235325
235324
  case diffMatchPatchExports.diff_match_patch.DIFF_INSERT: // Added text
235326
- /**
235327
- tobeMarkDecos.push({
235328
- from: tobeCursor,
235329
- to: tobeCursor + len,
235330
- deco: Decoration.mark({ class: "cm-inserted-inline" })
235331
- }); */
235332
-
235333
235325
  let currentTobeLineOffset = tobeCursor;
235334
235326
  const tobeLines = text.split('\n');
235335
235327
  for (let i = 0; i < tobeLines.length; i++) {
235328
+ // 줄의 시작 오프셋이 tobeDoc의 길이를 넘지 않는지 확인
235336
235329
  if (currentTobeLineOffset < tobeDoc.length) {
235337
235330
  const line = tobeDoc.lineAt(currentTobeLineOffset);
235338
235331
  tobeLineDecos.push({
@@ -235341,26 +235334,21 @@ export default DocManager;
235341
235334
  deco: Decoration.line({ class: "cm-inserted-line-bg" })
235342
235335
  });
235343
235336
  }
235337
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
235344
235338
  currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
235339
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
235345
235340
  if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
235346
235341
  break;
235347
235342
  }
235348
235343
  }
235349
-
235350
235344
  tobeCursor += len;
235351
235345
  break;
235352
235346
 
235353
235347
  case diffMatchPatchExports.diff_match_patch.DIFF_DELETE: // Deleted text
235354
- /**
235355
- asisMarkDecos.push({
235356
- from: asisCursor,
235357
- to: asisCursor + len,
235358
- deco: Decoration.mark({ class: "cm-deleted-inline" })
235359
- }); */
235360
-
235361
235348
  let currentAsisLineOffset = asisCursor;
235362
235349
  const asisLines = text.split('\n');
235363
235350
  for (let i = 0; i < asisLines.length; i++) {
235351
+ // 줄의 시작 오프셋이 asisDoc의 길이를 넘지 않는지 확인
235364
235352
  if (currentAsisLineOffset < asisDoc.length) {
235365
235353
  const line = asisDoc.lineAt(currentAsisLineOffset);
235366
235354
  asisLineDecos.push({
@@ -235369,12 +235357,13 @@ export default DocManager;
235369
235357
  deco: Decoration.line({ class: "cm-deleted-line-bg" })
235370
235358
  });
235371
235359
  }
235360
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
235372
235361
  currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
235362
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
235373
235363
  if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
235374
235364
  break;
235375
235365
  }
235376
235366
  }
235377
-
235378
235367
  asisCursor += len;
235379
235368
  break;
235380
235369
 
@@ -235385,34 +235374,22 @@ export default DocManager;
235385
235374
  }
235386
235375
  }
235387
235376
 
235377
+ // 데코레이션 중복 및 겹침 방지를 위해 정렬
235388
235378
  asisLineDecos.sort((a, b) => a.from - b.from);
235389
- asisMarkDecos.sort((a, b) => a.from - b.from);
235390
235379
  tobeLineDecos.sort((a, b) => a.from - b.from);
235391
- tobeMarkDecos.sort((a, b) => a.from - b.from);
235392
235380
 
235381
+ // 라인 데코레이션 빌더 생성
235393
235382
  const asisLineBuilder = new RangeSetBuilder();
235394
235383
  for (const { from, to, deco } of asisLineDecos) {
235395
235384
  asisLineBuilder.add(from, to, deco);
235396
235385
  }
235397
- const asisMarkBuilder = new RangeSetBuilder();
235398
- for (const { from, to, deco } of asisMarkDecos) {
235399
- asisMarkBuilder.add(from, to, deco);
235400
- }
235401
- const finalAsisDecorations = asisLineBuilder.finish().update({
235402
- add: asisMarkBuilder.finish().children
235403
- });
235386
+ const finalAsisDecorations = asisLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
235404
235387
 
235405
235388
  const tobeLineBuilder = new RangeSetBuilder();
235406
235389
  for (const { from, to, deco } of tobeLineDecos) {
235407
235390
  tobeLineBuilder.add(from, to, deco);
235408
235391
  }
235409
- const tobeMarkBuilder = new RangeSetBuilder();
235410
- for (const { from, to, deco } of tobeMarkDecos) {
235411
- tobeMarkBuilder.add(from, to, deco);
235412
- }
235413
- const finalTobeDecorations = tobeLineBuilder.finish().update({
235414
- add: tobeMarkBuilder.finish().children
235415
- });
235392
+ const finalTobeDecorations = tobeLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
235416
235393
 
235417
235394
  return {
235418
235395
  asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
@@ -235438,7 +235415,7 @@ export default DocManager;
235438
235415
  }
235439
235416
 
235440
235417
  // 데코레이션 효과는 미리 계산해 둡니다.
235441
- //const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
235418
+ const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
235442
235419
 
235443
235420
  // 1단계: 텍스트 내용 변경과 언어 확장을 먼저 디스패치합니다.
235444
235421
  // 'to' 값을 현재 문서 길이 전체로 지정하여 정확한 교체를 보장합니다.
@@ -235456,7 +235433,6 @@ export default DocManager;
235456
235433
  ]
235457
235434
  });
235458
235435
 
235459
- /**
235460
235436
  // ⭐️ 2단계: 텍스트 및 언어 변경이 완전히 적용되고 뷰가 안정화될 시간을 줍니다.
235461
235437
  // 다음 프레임에서 데코레이션 효과만 별도로 디스패치합니다.
235462
235438
  requestAnimationFrame(() => {
@@ -235475,7 +235451,7 @@ export default DocManager;
235475
235451
  // this.#asisEditorView.scrollDOM.scrollTop = 0;
235476
235452
  // this.#tobeEditorView.scrollDOM.scrollTop = 0;
235477
235453
  });
235478
- }); */
235454
+ });
235479
235455
  };
235480
235456
 
235481
235457
  disconnectedCallback() {
@@ -479,7 +479,7 @@ export default DocManager;
479
479
  javascript(),
480
480
  EditorState.readOnly.of(true),
481
481
  this.#languageCompartment.of(javascript()),
482
- //asisDiffDecorations,
482
+ asisDiffDecorations,
483
483
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
484
484
  EditorView.updateListener.of((update) => {
485
485
  if (update.view.contentDOM.firstChild && !update.view._initialAsisContentLoaded) {
@@ -501,7 +501,7 @@ export default DocManager;
501
501
  javascript(),
502
502
  EditorState.readOnly.of(true),
503
503
  this.#languageCompartment.of(javascript()),
504
- //tobeDiffDecorations,
504
+ tobeDiffDecorations,
505
505
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
506
506
  EditorView.updateListener.of((update) => {
507
507
  if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
@@ -552,20 +552,19 @@ export default DocManager;
552
552
  this.#tobeEditorView.scrollDOM.addEventListener('scroll', this._tobeScrollHandler);
553
553
  };
554
554
 
555
+ // IdeDiff 클래스 내부
555
556
  #applyDiffDecorations = (asisSrc, tobeSrc) => {
556
557
  const dmp = new diff_match_patch();
557
558
  const diffs = dmp.diff_main(asisSrc, tobeSrc);
558
559
  dmp.diff_cleanupSemantic(diffs);
559
560
 
560
561
  const asisLineDecos = [];
561
- const asisMarkDecos = [];
562
562
  const tobeLineDecos = [];
563
- const tobeMarkDecos = [];
564
563
 
565
564
  let asisCursor = 0;
566
565
  let tobeCursor = 0;
567
566
 
568
- // ⭐️ 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
567
+ // 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
569
568
  // 이 Doc 객체를 사용하여 lineAt()을 호출합니다.
570
569
  const asisDoc = Text.of(asisSrc.split('\n'));
571
570
  const tobeDoc = Text.of(tobeSrc.split('\n'));
@@ -575,16 +574,10 @@ export default DocManager;
575
574
 
576
575
  switch (op) {
577
576
  case diff_match_patch.DIFF_INSERT: // Added text
578
- /**
579
- tobeMarkDecos.push({
580
- from: tobeCursor,
581
- to: tobeCursor + len,
582
- deco: Decoration.mark({ class: "cm-inserted-inline" })
583
- }); */
584
-
585
577
  let currentTobeLineOffset = tobeCursor;
586
578
  const tobeLines = text.split('\n');
587
579
  for (let i = 0; i < tobeLines.length; i++) {
580
+ // 줄의 시작 오프셋이 tobeDoc의 길이를 넘지 않는지 확인
588
581
  if (currentTobeLineOffset < tobeDoc.length) {
589
582
  const line = tobeDoc.lineAt(currentTobeLineOffset);
590
583
  tobeLineDecos.push({
@@ -593,26 +586,21 @@ export default DocManager;
593
586
  deco: Decoration.line({ class: "cm-inserted-line-bg" })
594
587
  });
595
588
  }
589
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
596
590
  currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
591
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
597
592
  if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
598
593
  break;
599
594
  }
600
595
  }
601
-
602
596
  tobeCursor += len;
603
597
  break;
604
598
 
605
599
  case diff_match_patch.DIFF_DELETE: // Deleted text
606
- /**
607
- asisMarkDecos.push({
608
- from: asisCursor,
609
- to: asisCursor + len,
610
- deco: Decoration.mark({ class: "cm-deleted-inline" })
611
- }); */
612
-
613
600
  let currentAsisLineOffset = asisCursor;
614
601
  const asisLines = text.split('\n');
615
602
  for (let i = 0; i < asisLines.length; i++) {
603
+ // 줄의 시작 오프셋이 asisDoc의 길이를 넘지 않는지 확인
616
604
  if (currentAsisLineOffset < asisDoc.length) {
617
605
  const line = asisDoc.lineAt(currentAsisLineOffset);
618
606
  asisLineDecos.push({
@@ -621,12 +609,13 @@ export default DocManager;
621
609
  deco: Decoration.line({ class: "cm-deleted-line-bg" })
622
610
  });
623
611
  }
612
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
624
613
  currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
614
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
625
615
  if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
626
616
  break;
627
617
  }
628
618
  }
629
-
630
619
  asisCursor += len;
631
620
  break;
632
621
 
@@ -637,34 +626,22 @@ export default DocManager;
637
626
  }
638
627
  }
639
628
 
629
+ // 데코레이션 중복 및 겹침 방지를 위해 정렬
640
630
  asisLineDecos.sort((a, b) => a.from - b.from);
641
- asisMarkDecos.sort((a, b) => a.from - b.from);
642
631
  tobeLineDecos.sort((a, b) => a.from - b.from);
643
- tobeMarkDecos.sort((a, b) => a.from - b.from);
644
632
 
633
+ // 라인 데코레이션 빌더 생성
645
634
  const asisLineBuilder = new RangeSetBuilder();
646
635
  for (const { from, to, deco } of asisLineDecos) {
647
636
  asisLineBuilder.add(from, to, deco);
648
637
  }
649
- const asisMarkBuilder = new RangeSetBuilder();
650
- for (const { from, to, deco } of asisMarkDecos) {
651
- asisMarkBuilder.add(from, to, deco);
652
- }
653
- const finalAsisDecorations = asisLineBuilder.finish().update({
654
- add: asisMarkBuilder.finish().children
655
- });
638
+ const finalAsisDecorations = asisLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
656
639
 
657
640
  const tobeLineBuilder = new RangeSetBuilder();
658
641
  for (const { from, to, deco } of tobeLineDecos) {
659
642
  tobeLineBuilder.add(from, to, deco);
660
643
  }
661
- const tobeMarkBuilder = new RangeSetBuilder();
662
- for (const { from, to, deco } of tobeMarkDecos) {
663
- tobeMarkBuilder.add(from, to, deco);
664
- }
665
- const finalTobeDecorations = tobeLineBuilder.finish().update({
666
- add: tobeMarkBuilder.finish().children
667
- });
644
+ const finalTobeDecorations = tobeLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
668
645
 
669
646
  return {
670
647
  asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
@@ -690,7 +667,7 @@ export default DocManager;
690
667
  }
691
668
 
692
669
  // 데코레이션 효과는 미리 계산해 둡니다.
693
- //const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
670
+ const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
694
671
 
695
672
  // 1단계: 텍스트 내용 변경과 언어 확장을 먼저 디스패치합니다.
696
673
  // 'to' 값을 현재 문서 길이 전체로 지정하여 정확한 교체를 보장합니다.
@@ -708,7 +685,6 @@ export default DocManager;
708
685
  ]
709
686
  });
710
687
 
711
- /**
712
688
  // ⭐️ 2단계: 텍스트 및 언어 변경이 완전히 적용되고 뷰가 안정화될 시간을 줍니다.
713
689
  // 다음 프레임에서 데코레이션 효과만 별도로 디스패치합니다.
714
690
  requestAnimationFrame(() => {
@@ -727,7 +703,7 @@ export default DocManager;
727
703
  // this.#asisEditorView.scrollDOM.scrollTop = 0;
728
704
  // this.#tobeEditorView.scrollDOM.scrollTop = 0;
729
705
  });
730
- }); */
706
+ });
731
707
  };
732
708
 
733
709
  disconnectedCallback() {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ide-assi",
3
3
  "type": "module",
4
- "version": "0.384.0",
4
+ "version": "0.387.0",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "exports": {
@@ -479,7 +479,7 @@ export default DocManager;
479
479
  javascript(),
480
480
  EditorState.readOnly.of(true),
481
481
  this.#languageCompartment.of(javascript()),
482
- //asisDiffDecorations,
482
+ asisDiffDecorations,
483
483
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
484
484
  EditorView.updateListener.of((update) => {
485
485
  if (update.view.contentDOM.firstChild && !update.view._initialAsisContentLoaded) {
@@ -501,7 +501,7 @@ export default DocManager;
501
501
  javascript(),
502
502
  EditorState.readOnly.of(true),
503
503
  this.#languageCompartment.of(javascript()),
504
- //tobeDiffDecorations,
504
+ tobeDiffDecorations,
505
505
  // ⭐️ updateListener는 유지: 뷰가 DOM에 완전히 렌더링될 때까지 기다림
506
506
  EditorView.updateListener.of((update) => {
507
507
  if (update.view.contentDOM.firstChild && !update.view._initialTobeContentLoaded) {
@@ -552,20 +552,19 @@ export default DocManager;
552
552
  this.#tobeEditorView.scrollDOM.addEventListener('scroll', this._tobeScrollHandler);
553
553
  };
554
554
 
555
+ // IdeDiff 클래스 내부
555
556
  #applyDiffDecorations = (asisSrc, tobeSrc) => {
556
557
  const dmp = new diff_match_patch();
557
558
  const diffs = dmp.diff_main(asisSrc, tobeSrc);
558
559
  dmp.diff_cleanupSemantic(diffs);
559
560
 
560
561
  const asisLineDecos = [];
561
- const asisMarkDecos = [];
562
562
  const tobeLineDecos = [];
563
- const tobeMarkDecos = [];
564
563
 
565
564
  let asisCursor = 0;
566
565
  let tobeCursor = 0;
567
566
 
568
- // ⭐️ 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
567
+ // 중요: 새로운 문서 내용을 기반으로 임시 Doc 객체를 생성합니다.
569
568
  // 이 Doc 객체를 사용하여 lineAt()을 호출합니다.
570
569
  const asisDoc = Text.of(asisSrc.split('\n'));
571
570
  const tobeDoc = Text.of(tobeSrc.split('\n'));
@@ -575,16 +574,10 @@ export default DocManager;
575
574
 
576
575
  switch (op) {
577
576
  case diff_match_patch.DIFF_INSERT: // Added text
578
- /**
579
- tobeMarkDecos.push({
580
- from: tobeCursor,
581
- to: tobeCursor + len,
582
- deco: Decoration.mark({ class: "cm-inserted-inline" })
583
- }); */
584
-
585
577
  let currentTobeLineOffset = tobeCursor;
586
578
  const tobeLines = text.split('\n');
587
579
  for (let i = 0; i < tobeLines.length; i++) {
580
+ // 줄의 시작 오프셋이 tobeDoc의 길이를 넘지 않는지 확인
588
581
  if (currentTobeLineOffset < tobeDoc.length) {
589
582
  const line = tobeDoc.lineAt(currentTobeLineOffset);
590
583
  tobeLineDecos.push({
@@ -593,26 +586,21 @@ export default DocManager;
593
586
  deco: Decoration.line({ class: "cm-inserted-line-bg" })
594
587
  });
595
588
  }
589
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
596
590
  currentTobeLineOffset += tobeLines[i].length + (i < tobeLines.length - 1 ? 1 : 0);
591
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
597
592
  if (i === tobeLines.length - 1 && tobeLines[i].length === 0 && text.endsWith('\n') === false) {
598
593
  break;
599
594
  }
600
595
  }
601
-
602
596
  tobeCursor += len;
603
597
  break;
604
598
 
605
599
  case diff_match_patch.DIFF_DELETE: // Deleted text
606
- /**
607
- asisMarkDecos.push({
608
- from: asisCursor,
609
- to: asisCursor + len,
610
- deco: Decoration.mark({ class: "cm-deleted-inline" })
611
- }); */
612
-
613
600
  let currentAsisLineOffset = asisCursor;
614
601
  const asisLines = text.split('\n');
615
602
  for (let i = 0; i < asisLines.length; i++) {
603
+ // 줄의 시작 오프셋이 asisDoc의 길이를 넘지 않는지 확인
616
604
  if (currentAsisLineOffset < asisDoc.length) {
617
605
  const line = asisDoc.lineAt(currentAsisLineOffset);
618
606
  asisLineDecos.push({
@@ -621,12 +609,13 @@ export default DocManager;
621
609
  deco: Decoration.line({ class: "cm-deleted-line-bg" })
622
610
  });
623
611
  }
612
+ // 다음 줄의 시작 오프셋 계산 (개행 문자 고려)
624
613
  currentAsisLineOffset += asisLines[i].length + (i < asisLines.length - 1 ? 1 : 0);
614
+ // 마지막 줄이 비어 있고 개행으로 끝나지 않으면 루프 종료 (lineAt 오류 방지)
625
615
  if (i === asisLines.length - 1 && asisLines[i].length === 0 && text.endsWith('\n') === false) {
626
616
  break;
627
617
  }
628
618
  }
629
-
630
619
  asisCursor += len;
631
620
  break;
632
621
 
@@ -637,34 +626,22 @@ export default DocManager;
637
626
  }
638
627
  }
639
628
 
629
+ // 데코레이션 중복 및 겹침 방지를 위해 정렬
640
630
  asisLineDecos.sort((a, b) => a.from - b.from);
641
- asisMarkDecos.sort((a, b) => a.from - b.from);
642
631
  tobeLineDecos.sort((a, b) => a.from - b.from);
643
- tobeMarkDecos.sort((a, b) => a.from - b.from);
644
632
 
633
+ // 라인 데코레이션 빌더 생성
645
634
  const asisLineBuilder = new RangeSetBuilder();
646
635
  for (const { from, to, deco } of asisLineDecos) {
647
636
  asisLineBuilder.add(from, to, deco);
648
637
  }
649
- const asisMarkBuilder = new RangeSetBuilder();
650
- for (const { from, to, deco } of asisMarkDecos) {
651
- asisMarkBuilder.add(from, to, deco);
652
- }
653
- const finalAsisDecorations = asisLineBuilder.finish().update({
654
- add: asisMarkBuilder.finish().children
655
- });
638
+ const finalAsisDecorations = asisLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
656
639
 
657
640
  const tobeLineBuilder = new RangeSetBuilder();
658
641
  for (const { from, to, deco } of tobeLineDecos) {
659
642
  tobeLineBuilder.add(from, to, deco);
660
643
  }
661
- const tobeMarkBuilder = new RangeSetBuilder();
662
- for (const { from, to, deco } of tobeMarkDecos) {
663
- tobeMarkBuilder.add(from, to, deco);
664
- }
665
- const finalTobeDecorations = tobeLineBuilder.finish().update({
666
- add: tobeMarkBuilder.finish().children
667
- });
644
+ const finalTobeDecorations = tobeLineBuilder.finish(); // ⭐️ .update({ add: ... }) 부분 제거
668
645
 
669
646
  return {
670
647
  asisEffect: setAsisDecorationsEffect.of(finalAsisDecorations),
@@ -690,7 +667,7 @@ export default DocManager;
690
667
  }
691
668
 
692
669
  // 데코레이션 효과는 미리 계산해 둡니다.
693
- //const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
670
+ const { asisEffect, tobeEffect } = this.#applyDiffDecorations(src1, src2);
694
671
 
695
672
  // 1단계: 텍스트 내용 변경과 언어 확장을 먼저 디스패치합니다.
696
673
  // 'to' 값을 현재 문서 길이 전체로 지정하여 정확한 교체를 보장합니다.
@@ -708,7 +685,6 @@ export default DocManager;
708
685
  ]
709
686
  });
710
687
 
711
- /**
712
688
  // ⭐️ 2단계: 텍스트 및 언어 변경이 완전히 적용되고 뷰가 안정화될 시간을 줍니다.
713
689
  // 다음 프레임에서 데코레이션 효과만 별도로 디스패치합니다.
714
690
  requestAnimationFrame(() => {
@@ -727,7 +703,7 @@ export default DocManager;
727
703
  // this.#asisEditorView.scrollDOM.scrollTop = 0;
728
704
  // this.#tobeEditorView.scrollDOM.scrollTop = 0;
729
705
  });
730
- }); */
706
+ });
731
707
  };
732
708
 
733
709
  disconnectedCallback() {