muggle-string 0.3.0 → 0.4.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.
package/out/base.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Range, Segment } from './types';
2
+ export declare function getLength(segments: Segment<any>[]): number;
3
+ export declare function toString<T extends Segment<any>>(segments: T[]): string;
4
+ export declare function replace<T extends Segment<any>>(segments: T[], pattern: string | RegExp, ...replacers: (T | ((match: string) => T))[]): void;
5
+ export declare function replaceAll<T extends Segment<any>>(segments: T[], pattern: RegExp, ...replacers: (T | ((match: string) => T))[]): void;
6
+ export declare function overwrite<T extends Segment<any>>(segments: T[], range: number | Range, ...inserts: T[]): T[];
package/out/base.js ADDED
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.overwrite = exports.replaceAll = exports.replace = exports.toString = exports.getLength = void 0;
4
+ const binarySearch_1 = require("./binarySearch");
5
+ const track_1 = require("./track");
6
+ function getLength(segments) {
7
+ let length = 0;
8
+ for (const segment of segments) {
9
+ length += typeof segment == 'string' ? segment.length : segment[0].length;
10
+ }
11
+ return length;
12
+ }
13
+ exports.getLength = getLength;
14
+ function toString(segments) {
15
+ return segments.map(s => typeof s === 'string' ? s : s[0]).join('');
16
+ }
17
+ exports.toString = toString;
18
+ function replace(segments, pattern, ...replacers) {
19
+ const str = toString(segments);
20
+ const match = str.match(pattern);
21
+ if (match && match.index !== undefined) {
22
+ const start = match.index;
23
+ const end = start + match[0].length;
24
+ (0, track_1.offsetStack)();
25
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
26
+ (0, track_1.resetOffsetStack)();
27
+ }
28
+ }
29
+ exports.replace = replace;
30
+ function replaceAll(segments, pattern, ...replacers) {
31
+ const str = toString(segments);
32
+ const allMatch = str.matchAll(pattern);
33
+ let length = str.length;
34
+ let lengthDiff = 0;
35
+ for (const match of allMatch) {
36
+ if (match.index !== undefined) {
37
+ const start = match.index + lengthDiff;
38
+ const end = start + match[0].length;
39
+ (0, track_1.offsetStack)();
40
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
41
+ (0, track_1.resetOffsetStack)();
42
+ const newLength = getLength(segments);
43
+ lengthDiff += newLength - length;
44
+ length = newLength;
45
+ }
46
+ }
47
+ }
48
+ exports.replaceAll = replaceAll;
49
+ function overwrite(segments, range, ...inserts) {
50
+ const offsets = toOffsets(segments);
51
+ const [start, end] = typeof range === 'number' ? [range, range] : range;
52
+ const startIndex = (0, binarySearch_1.binarySearch)(offsets, start);
53
+ const endIndex = (0, binarySearch_1.binarySearch)(offsets, end);
54
+ const startSegment = segments[startIndex];
55
+ const endSegment = segments[endIndex];
56
+ const startSegmentStart = offsets[startIndex];
57
+ const endSegmentStart = offsets[endIndex];
58
+ const endSegmentEnd = offsets[endIndex] + (typeof endSegment === 'string' ? endSegment.length : endSegment[0].length);
59
+ if (start > startSegmentStart) {
60
+ inserts.unshift(trimSegmentEnd(startSegment, start - startSegmentStart));
61
+ }
62
+ if (end < endSegmentEnd) {
63
+ inserts.push(trimSegmentStart(endSegment, end - endSegmentStart));
64
+ }
65
+ (0, track_1.offsetStack)();
66
+ const deleted = segments.splice(startIndex, endIndex - startIndex + 1, ...inserts);
67
+ (0, track_1.resetOffsetStack)();
68
+ if (end < endSegmentEnd) {
69
+ deleted[deleted.length - 1] = trimSegmentEnd(deleted[deleted.length - 1], end - endSegmentStart);
70
+ }
71
+ if (start > startSegmentStart) {
72
+ deleted[0] = trimSegmentStart(deleted[0], start - startSegmentStart);
73
+ }
74
+ return deleted;
75
+ }
76
+ exports.overwrite = overwrite;
77
+ function trimSegmentEnd(segment, trimEnd) {
78
+ if (typeof segment === 'string') {
79
+ return segment.slice(0, trimEnd);
80
+ }
81
+ const originalString = segment[0];
82
+ const originalRange = segment[2];
83
+ const newString = originalString.slice(0, trimEnd);
84
+ const newRange = typeof originalRange === 'number' ? originalRange : [originalRange[0], originalRange[1] - (originalString.length - newString.length)];
85
+ return [
86
+ newString,
87
+ segment[1],
88
+ newRange,
89
+ ...segment.slice(3),
90
+ ];
91
+ }
92
+ function trimSegmentStart(segment, trimStart) {
93
+ if (typeof segment === 'string') {
94
+ return segment.slice(trimStart);
95
+ }
96
+ const originalString = segment[0];
97
+ const originalRange = segment[2];
98
+ const newString = originalString.slice(trimStart);
99
+ if (trimStart < 0) {
100
+ trimStart += originalString.length;
101
+ }
102
+ const newRange = typeof originalRange === 'number' ? originalRange + trimStart : [originalRange[0] + trimStart, originalRange[1]];
103
+ return [
104
+ newString,
105
+ segment[1],
106
+ newRange,
107
+ ...segment.slice(3),
108
+ ];
109
+ }
110
+ function toOffsets(segments) {
111
+ const offsets = [];
112
+ let offset = 0;
113
+ for (const segment of segments) {
114
+ offsets.push(offset);
115
+ offset += typeof segment == 'string' ? segment.length : segment[0].length;
116
+ }
117
+ return offsets;
118
+ }
119
+ //# sourceMappingURL=base.js.map
package/out/basic.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { Range, Segment } from './types';
2
+ export declare function getLength(segments: Segment<any>[]): number;
3
+ export declare function toString<T extends Segment<any>>(segments: T[]): string;
4
+ export declare function replace<T extends Segment<any>>(segments: T[], pattern: string | RegExp, ...replacers: (T | ((match: string) => T))[]): void;
5
+ export declare function replaceAll<T extends Segment<any>>(segments: T[], pattern: RegExp, ...replacers: (T | ((match: string) => T))[]): void;
6
+ export declare function overwrite<T extends Segment<any>>(segments: T[], range: number | Range, ...inserts: T[]): T[];
package/out/basic.js ADDED
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.overwrite = exports.replaceAll = exports.replace = exports.toString = exports.getLength = void 0;
4
+ const binarySearch_1 = require("./binarySearch");
5
+ const track_1 = require("./track");
6
+ function getLength(segments) {
7
+ let length = 0;
8
+ for (const segment of segments) {
9
+ length += typeof segment == 'string' ? segment.length : segment[0].length;
10
+ }
11
+ return length;
12
+ }
13
+ exports.getLength = getLength;
14
+ function toString(segments) {
15
+ return segments.map(s => typeof s === 'string' ? s : s[0]).join('');
16
+ }
17
+ exports.toString = toString;
18
+ function replace(segments, pattern, ...replacers) {
19
+ const str = toString(segments);
20
+ const match = str.match(pattern);
21
+ if (match && match.index !== undefined) {
22
+ const start = match.index;
23
+ const end = start + match[0].length;
24
+ (0, track_1.offsetStack)();
25
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
26
+ (0, track_1.resetOffsetStack)();
27
+ }
28
+ }
29
+ exports.replace = replace;
30
+ function replaceAll(segments, pattern, ...replacers) {
31
+ const str = toString(segments);
32
+ const allMatch = str.matchAll(pattern);
33
+ let length = str.length;
34
+ let lengthDiff = 0;
35
+ for (const match of allMatch) {
36
+ if (match.index !== undefined) {
37
+ const start = match.index + lengthDiff;
38
+ const end = start + match[0].length;
39
+ (0, track_1.offsetStack)();
40
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
41
+ (0, track_1.resetOffsetStack)();
42
+ const newLength = getLength(segments);
43
+ lengthDiff += newLength - length;
44
+ length = newLength;
45
+ }
46
+ }
47
+ }
48
+ exports.replaceAll = replaceAll;
49
+ function overwrite(segments, range, ...inserts) {
50
+ const offsets = toOffsets(segments);
51
+ const [start, end] = typeof range === 'number' ? [range, range] : range;
52
+ const startIndex = (0, binarySearch_1.binarySearch)(offsets, start);
53
+ const endIndex = (0, binarySearch_1.binarySearch)(offsets, end);
54
+ const startSegment = segments[startIndex];
55
+ const endSegment = segments[endIndex];
56
+ const startSegmentStart = offsets[startIndex];
57
+ const endSegmentStart = offsets[endIndex];
58
+ const endSegmentEnd = offsets[endIndex] + (typeof endSegment === 'string' ? endSegment.length : endSegment[0].length);
59
+ if (start > startSegmentStart) {
60
+ inserts.unshift(trimSegmentEnd(startSegment, start - startSegmentStart));
61
+ }
62
+ if (end < endSegmentEnd) {
63
+ inserts.push(trimSegmentStart(endSegment, end - endSegmentStart));
64
+ }
65
+ (0, track_1.offsetStack)();
66
+ const deleted = segments.splice(startIndex, endIndex - startIndex + 1, ...inserts);
67
+ (0, track_1.resetOffsetStack)();
68
+ if (end < endSegmentEnd) {
69
+ deleted[deleted.length - 1] = trimSegmentEnd(deleted[deleted.length - 1], end - endSegmentStart);
70
+ }
71
+ if (start > startSegmentStart) {
72
+ deleted[0] = trimSegmentStart(deleted[0], start - startSegmentStart);
73
+ }
74
+ return deleted;
75
+ }
76
+ exports.overwrite = overwrite;
77
+ function trimSegmentEnd(segment, trimEnd) {
78
+ if (typeof segment === 'string') {
79
+ return segment.slice(0, trimEnd);
80
+ }
81
+ const originalString = segment[0];
82
+ const originalRange = segment[2];
83
+ const newString = originalString.slice(0, trimEnd);
84
+ const newRange = typeof originalRange === 'number' ? originalRange : [originalRange[0], originalRange[1] - (originalString.length - newString.length)];
85
+ return [
86
+ newString,
87
+ segment[1],
88
+ newRange,
89
+ ...segment.slice(3),
90
+ ];
91
+ }
92
+ function trimSegmentStart(segment, trimStart) {
93
+ if (typeof segment === 'string') {
94
+ return segment.slice(trimStart);
95
+ }
96
+ const originalString = segment[0];
97
+ const originalRange = segment[2];
98
+ const newString = originalString.slice(trimStart);
99
+ if (trimStart < 0) {
100
+ trimStart += originalString.length;
101
+ }
102
+ const newRange = typeof originalRange === 'number' ? originalRange + trimStart : [originalRange[0] + trimStart, originalRange[1]];
103
+ return [
104
+ newString,
105
+ segment[1],
106
+ newRange,
107
+ ...segment.slice(3),
108
+ ];
109
+ }
110
+ function toOffsets(segments) {
111
+ const offsets = [];
112
+ let offset = 0;
113
+ for (const segment of segments) {
114
+ offsets.push(offset);
115
+ offset += typeof segment == 'string' ? segment.length : segment[0].length;
116
+ }
117
+ return offsets;
118
+ }
119
+ //# sourceMappingURL=basic.js.map
@@ -0,0 +1,9 @@
1
+ import { Range, Segment } from './types';
2
+ export * from './types';
3
+ export * from './track';
4
+ export * from './segment';
5
+ export declare function getLength(segments: Segment<any>[]): number;
6
+ export declare function toString<T extends Segment<any>>(segments: T[]): string;
7
+ export declare function replace<T extends Segment<any>>(segments: T[], pattern: string | RegExp, ...replacers: (T | ((match: string) => T))[]): void;
8
+ export declare function replaceAll<T extends Segment<any>>(segments: T[], pattern: RegExp, ...replacers: (T | ((match: string) => T))[]): void;
9
+ export declare function overwrite<T extends Segment<any>>(segments: T[], range: number | Range, ...inserts: T[]): void;
package/out/common.js ADDED
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.overwrite = exports.replaceAll = exports.replace = exports.toString = exports.getLength = void 0;
18
+ const binarySearch_1 = require("./binarySearch");
19
+ const track_1 = require("./track");
20
+ __exportStar(require("./types"), exports);
21
+ __exportStar(require("./track"), exports);
22
+ __exportStar(require("./segment"), exports);
23
+ function getLength(segments) {
24
+ let length = 0;
25
+ for (const segment of segments) {
26
+ length += typeof segment == 'string' ? segment.length : segment[0].length;
27
+ }
28
+ return length;
29
+ }
30
+ exports.getLength = getLength;
31
+ function toString(segments) {
32
+ return segments.map(s => typeof s === 'string' ? s : s[0]).join('');
33
+ }
34
+ exports.toString = toString;
35
+ function replace(segments, pattern, ...replacers) {
36
+ const str = toString(segments);
37
+ const match = str.match(pattern);
38
+ if (match && match.index !== undefined) {
39
+ const start = match.index;
40
+ const end = start + match[0].length;
41
+ (0, track_1.offsetStack)();
42
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
43
+ (0, track_1.resetOffsetStack)();
44
+ }
45
+ }
46
+ exports.replace = replace;
47
+ function replaceAll(segments, pattern, ...replacers) {
48
+ const str = toString(segments);
49
+ const allMatch = str.matchAll(pattern);
50
+ let length = str.length;
51
+ let lengthDiff = 0;
52
+ for (const match of allMatch) {
53
+ if (match.index !== undefined) {
54
+ const start = match.index + lengthDiff;
55
+ const end = start + match[0].length;
56
+ (0, track_1.offsetStack)();
57
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
58
+ (0, track_1.resetOffsetStack)();
59
+ const newLength = getLength(segments);
60
+ lengthDiff += newLength - length;
61
+ length = newLength;
62
+ }
63
+ }
64
+ }
65
+ exports.replaceAll = replaceAll;
66
+ function overwrite(segments, range, ...inserts) {
67
+ const offsets = toOffsets(segments);
68
+ const [start, end] = typeof range === 'number' ? [range, range] : range;
69
+ const startIndex = (0, binarySearch_1.binarySearch)(offsets, start);
70
+ const endIndex = (0, binarySearch_1.binarySearch)(offsets, end);
71
+ const startSegment = segments[startIndex];
72
+ const endSegment = segments[endIndex];
73
+ const startSegmentStart = offsets[startIndex];
74
+ const endSegmentStart = offsets[endIndex];
75
+ const endSegmentEnd = offsets[endIndex] + (typeof endSegment === 'string' ? endSegment.length : endSegment[0].length);
76
+ if (start > startSegmentStart) {
77
+ inserts.unshift(trimSegmentEnd(startSegment, start - startSegmentStart));
78
+ }
79
+ if (end < endSegmentEnd) {
80
+ inserts.push(trimSegmentStart(endSegment, end - endSegmentStart));
81
+ }
82
+ combineStrings(inserts);
83
+ (0, track_1.offsetStack)();
84
+ segments.splice(startIndex, endIndex - startIndex + 1, ...inserts);
85
+ (0, track_1.resetOffsetStack)();
86
+ }
87
+ exports.overwrite = overwrite;
88
+ function combineStrings(segments) {
89
+ for (let i = segments.length - 1; i >= 1; i--) {
90
+ if (typeof segments[i] === 'string' && typeof segments[i - 1] === 'string') {
91
+ segments[i - 1] = segments[i - 1] + segments[i];
92
+ (0, track_1.offsetStack)();
93
+ segments.splice(i, 1);
94
+ (0, track_1.resetOffsetStack)();
95
+ }
96
+ }
97
+ }
98
+ function trimSegmentEnd(segment, trimEnd) {
99
+ if (typeof segment === 'string') {
100
+ return segment.slice(0, trimEnd);
101
+ }
102
+ const originalString = segment[0];
103
+ const originalRange = segment[2];
104
+ const newString = originalString.slice(0, trimEnd);
105
+ const newRange = typeof originalRange === 'number' ? originalRange : [originalRange[0], originalRange[1] - (originalString.length - newString.length)];
106
+ return [
107
+ newString,
108
+ segment[1],
109
+ newRange,
110
+ ...segment.slice(3),
111
+ ];
112
+ }
113
+ function trimSegmentStart(segment, trimStart) {
114
+ if (typeof segment === 'string') {
115
+ return segment.slice(trimStart);
116
+ }
117
+ const originalString = segment[0];
118
+ const originalRange = segment[2];
119
+ const newString = originalString.slice(trimStart);
120
+ if (trimStart < 0) {
121
+ trimStart += originalString.length;
122
+ }
123
+ const newRange = typeof originalRange === 'number' ? originalRange + trimStart : [originalRange[0] + trimStart, originalRange[1]];
124
+ return [
125
+ newString,
126
+ segment[1],
127
+ newRange,
128
+ ...segment.slice(3),
129
+ ];
130
+ }
131
+ function toOffsets(segments) {
132
+ const offsets = [];
133
+ let offset = 0;
134
+ for (const segment of segments) {
135
+ offsets.push(offset);
136
+ offset += typeof segment == 'string' ? segment.length : segment[0].length;
137
+ }
138
+ return offsets;
139
+ }
140
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1,2 @@
1
+ import type { Segment } from './types';
2
+ export declare function getLength(segments: Segment<any>[]): number;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getLength = void 0;
4
+ function getLength(segments) {
5
+ let length = 0;
6
+ for (const segment of segments) {
7
+ length += typeof segment == 'string' ? segment.length : segment[0].length;
8
+ }
9
+ return length;
10
+ }
11
+ exports.getLength = getLength;
12
+ //# sourceMappingURL=getLength.js.map
package/out/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export * from './types';
3
3
  export * from './track';
4
4
  export declare function getLength(segments: Segment<any>[]): number;
5
5
  export declare function toString<T extends Segment<any>>(segments: T[]): string;
6
+ export declare function create(source: string): Segment[];
6
7
  export declare function replace<T extends Segment<any>>(segments: T[], pattern: string | RegExp, ...replacers: (T | ((match: string) => T))[]): void;
7
8
  export declare function replaceAll<T extends Segment<any>>(segments: T[], pattern: RegExp, ...replacers: (T | ((match: string) => T))[]): void;
8
9
  export declare function replaceSourceRange<T extends Segment<any>>(segments: T[], source: string | undefined, startOffset: number, endOffset: number, ...newSegments: T[]): boolean;
package/out/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.replaceRange = exports.replaceSourceRange = exports.replaceAll = exports.replace = exports.toString = exports.getLength = void 0;
17
+ exports.replaceRange = exports.replaceSourceRange = exports.replaceAll = exports.replace = exports.create = exports.toString = exports.getLength = void 0;
18
18
  const binarySearch_1 = require("./binarySearch");
19
19
  const track_1 = require("./track");
20
20
  __exportStar(require("./types"), exports);
@@ -31,6 +31,10 @@ function toString(segments) {
31
31
  return segments.map(s => typeof s === 'string' ? s : s[0]).join('');
32
32
  }
33
33
  exports.toString = toString;
34
+ function create(source) {
35
+ return [[source, undefined, 0]];
36
+ }
37
+ exports.create = create;
34
38
  function replace(segments, pattern, ...replacers) {
35
39
  const str = toString(segments);
36
40
  const match = str.match(pattern);
@@ -68,8 +72,8 @@ function replaceSourceRange(segments, source, startOffset, endOffset, ...newSegm
68
72
  continue;
69
73
  }
70
74
  if (segment[1] === source) {
71
- const segmentStart = typeof segment[2] === 'number' ? segment[2] : segment[2][0];
72
- const segmentEnd = typeof segment[2] === 'number' ? segment[2] + segment[0].length : segment[2][1];
75
+ const segmentStart = segment[2];
76
+ const segmentEnd = segment[2] + segment[0].length;
73
77
  if (segmentStart <= startOffset && segmentEnd >= endOffset) {
74
78
  const inserts = [];
75
79
  if (startOffset > segmentStart) {
@@ -131,32 +135,22 @@ function trimSegmentEnd(segment, trimEnd) {
131
135
  if (typeof segment === 'string') {
132
136
  return segment.slice(0, trimEnd);
133
137
  }
134
- const originalString = segment[0];
135
- const originalRange = segment[2];
136
- const newString = originalString.slice(0, trimEnd);
137
- const newRange = typeof originalRange === 'number' ? originalRange : [originalRange[0], originalRange[1] - (originalString.length - newString.length)];
138
138
  return [
139
- newString,
140
- segment[1],
141
- newRange,
142
- ...segment.slice(3),
139
+ segment[0].slice(0, trimEnd),
140
+ ...segment.slice(1),
143
141
  ];
144
142
  }
145
143
  function trimSegmentStart(segment, trimStart) {
146
144
  if (typeof segment === 'string') {
147
145
  return segment.slice(trimStart);
148
146
  }
149
- const originalString = segment[0];
150
- const originalRange = segment[2];
151
- const newString = originalString.slice(trimStart);
152
147
  if (trimStart < 0) {
153
- trimStart += originalString.length;
148
+ trimStart += segment[0].length;
154
149
  }
155
- const newRange = typeof originalRange === 'number' ? originalRange + trimStart : [originalRange[0] + trimStart, originalRange[1]];
156
150
  return [
157
- newString,
151
+ segment[0].slice(trimStart),
158
152
  segment[1],
159
- newRange,
153
+ segment[2] + trimStart,
160
154
  ...segment.slice(3),
161
155
  ];
162
156
  }
package/out/map.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import { Segment } from './types';
2
+ export declare function clone(segments: Segment<any>[]): Segment<any>[];
3
+ export declare function generateMap(segments: Segment<any>[], readSource: (source?: string) => [number, string]): string;
package/out/map.js ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateMap = exports.clone = void 0;
4
+ const sourcemap_codec_1 = require("@jridgewell/sourcemap-codec");
5
+ const vscode_languageserver_textdocument_1 = require("vscode-languageserver-textdocument");
6
+ const base_1 = require("./base");
7
+ function clone(segments) {
8
+ const cloned = [];
9
+ for (const s of segments) {
10
+ if (typeof s === 'string') {
11
+ cloned.push(s);
12
+ }
13
+ else {
14
+ cloned.push([...s]);
15
+ }
16
+ }
17
+ return cloned;
18
+ }
19
+ exports.clone = clone;
20
+ function generateMap(segments, readSource) {
21
+ const cloned = clone(segments);
22
+ const mappings = [];
23
+ const sourceCode = new Map();
24
+ let newLineIndex = (0, base_1.toString)(cloned).indexOf('\n');
25
+ while (newLineIndex >= 0) {
26
+ onLine((0, base_1.overwrite)(cloned, [0, newLineIndex + 1]));
27
+ newLineIndex = (0, base_1.toString)(cloned).indexOf('\n');
28
+ }
29
+ onLine((0, base_1.overwrite)(cloned, [0, (0, base_1.getLength)(cloned)]));
30
+ return (0, sourcemap_codec_1.encode)(mappings);
31
+ function onLine(lineSegments) {
32
+ const lineMapping = [];
33
+ let currentColumn = 0;
34
+ let hasCodeMapping = false;
35
+ for (const s of lineSegments) {
36
+ if (typeof s === 'string') {
37
+ if (hasCodeMapping) {
38
+ hasCodeMapping = false;
39
+ // we don't break off last mapping for now
40
+ }
41
+ currentColumn += s.length;
42
+ }
43
+ else {
44
+ hasCodeMapping = true;
45
+ const source = s[1];
46
+ const sourceOffset = s[2][0];
47
+ if (!sourceCode.has(source)) {
48
+ const readed = readSource(source);
49
+ sourceCode.set(source, [readed[0], vscode_languageserver_textdocument_1.TextDocument.create('', '', 0, readed[1])]);
50
+ }
51
+ const [sourceIndex, document] = sourceCode.get(source);
52
+ const position = document.positionAt(sourceOffset);
53
+ lineMapping.push([
54
+ currentColumn,
55
+ sourceIndex,
56
+ position.line,
57
+ position.character,
58
+ ]);
59
+ currentColumn += s[0].length;
60
+ }
61
+ }
62
+ mappings.push(lineMapping);
63
+ }
64
+ }
65
+ exports.generateMap = generateMap;
66
+ //# sourceMappingURL=map.js.map
@@ -0,0 +1,3 @@
1
+ import { Range, Segment } from './types';
2
+ export declare function overwriteSource<T extends Segment<any>>(segments: T[], sourceLoc: number | Range, ...newSegments: T[]): T[];
3
+ export declare function overwriteSource<T extends Segment<any>>(segments: T[], source: string, sourceLoc: number | Range, ...newSegments: T[]): T[];
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.overwriteSource = void 0;
4
+ const base_1 = require("./base");
5
+ function overwriteSource(segments, ...args) {
6
+ let loc;
7
+ let newSegments;
8
+ if (typeof args[0] === 'string') {
9
+ const source = args[0];
10
+ const sourceLoc = args[1];
11
+ loc = typeof sourceLoc === 'number'
12
+ ? searchSource(segments, source, sourceLoc)
13
+ : [searchSource(segments, source, sourceLoc[0]), searchSource(segments, source, sourceLoc[1])];
14
+ newSegments = args.slice(2);
15
+ }
16
+ else {
17
+ const sourceLoc = args[0];
18
+ loc = typeof sourceLoc === 'number'
19
+ ? searchSource(segments, sourceLoc)
20
+ : [searchSource(segments, sourceLoc[0]), searchSource(segments, sourceLoc[1])];
21
+ newSegments = args.slice(1);
22
+ }
23
+ return (0, base_1.overwrite)(segments, loc, ...newSegments);
24
+ }
25
+ exports.overwriteSource = overwriteSource;
26
+ function searchSource(segments, ...args) {
27
+ const source = args.length >= 2 ? args[0] : undefined;
28
+ const sourceLoc = args.length >= 2 ? args[1] : args[0];
29
+ let _offset = 0;
30
+ let result;
31
+ for (const segment of segments) {
32
+ if (typeof segment === 'string') {
33
+ _offset += segment.length;
34
+ continue;
35
+ }
36
+ if (segment[1] === source) {
37
+ const segmentStart = typeof segment[2] === 'number' ? segment[2] : segment[2][0];
38
+ const segmentEnd = typeof segment[2] === 'number' ? segment[2] + segment[0].length : segment[2][1];
39
+ if (sourceLoc >= segmentStart && sourceLoc <= segmentEnd) {
40
+ result = _offset + (sourceLoc - segmentStart);
41
+ break;
42
+ }
43
+ }
44
+ _offset += segment[0].length;
45
+ }
46
+ if (result === undefined) {
47
+ throw new Error(`Source index not found, source: ${source}, index: ${sourceLoc}`);
48
+ }
49
+ return result;
50
+ }
51
+ //# sourceMappingURL=overwriteSource.js.map
@@ -0,0 +1,3 @@
1
+ import type { Segment } from './types';
2
+ export declare function replace<T extends Segment<any>>(segments: T[], pattern: string | RegExp, ...replacers: (T | ((match: string) => T))[]): void;
3
+ export declare function replaceAll<T extends Segment<any>>(segments: T[], pattern: RegExp, ...replacers: (T | ((match: string) => T))[]): void;
package/out/replace.js ADDED
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.replaceAll = exports.replace = void 0;
4
+ function replace(segments, pattern, ...replacers) {
5
+ const str = toString(segments);
6
+ const match = str.match(pattern);
7
+ if (match && match.index !== undefined) {
8
+ const start = match.index;
9
+ const end = start + match[0].length;
10
+ offsetStack();
11
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
12
+ resetOffsetStack();
13
+ }
14
+ }
15
+ exports.replace = replace;
16
+ function replaceAll(segments, pattern, ...replacers) {
17
+ const str = toString(segments);
18
+ const allMatch = str.matchAll(pattern);
19
+ let length = str.length;
20
+ let lengthDiff = 0;
21
+ for (const match of allMatch) {
22
+ if (match.index !== undefined) {
23
+ const start = match.index + lengthDiff;
24
+ const end = start + match[0].length;
25
+ offsetStack();
26
+ overwrite(segments, [start, end], ...replacers.map(replacer => typeof replacer === 'function' ? replacer(match[0]) : replacer));
27
+ resetOffsetStack();
28
+ const newLength = getLength(segments);
29
+ lengthDiff += newLength - length;
30
+ length = newLength;
31
+ }
32
+ }
33
+ }
34
+ exports.replaceAll = replaceAll;
35
+ //# sourceMappingURL=replace.js.map
@@ -0,0 +1,6 @@
1
+ import { Segment, Range } from './types';
2
+ export declare function segment(text: string): Segment;
3
+ export declare function segment(text: string, start: number | Range): Segment;
4
+ export declare function segment<T>(text: string, start: number | Range, data: T): Segment<T>;
5
+ export declare function segment(text: string, source: string, start: number | Range): Segment;
6
+ export declare function segment<T>(text: string, source: string, start: number | Range, data: T): Segment<T>;
package/out/segment.js ADDED
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.segment = void 0;
4
+ function segment(...args) {
5
+ const text = args[0];
6
+ if (args.length === 1) {
7
+ return text;
8
+ }
9
+ let source;
10
+ let start;
11
+ let end;
12
+ let hasData = false;
13
+ let data;
14
+ if (typeof args[1] !== 'number') {
15
+ source = args[1];
16
+ start = typeof args[2] == 'number' ? args[2] : args[2][0];
17
+ end = typeof args[2] == 'number' ? args[2] + text.length : args[2][1];
18
+ hasData = args.length >= 4;
19
+ if (hasData) {
20
+ data = args[3];
21
+ }
22
+ }
23
+ else {
24
+ start = typeof args[1] == 'number' ? args[1] : args[1][0];
25
+ end = typeof args[1] == 'number' ? args[1] + text.length : args[1][1];
26
+ hasData = args.length >= 3;
27
+ if (hasData) {
28
+ data = args[2];
29
+ }
30
+ }
31
+ if (hasData) {
32
+ return [text, source, [start, end], data];
33
+ }
34
+ else {
35
+ return [text, source, [start, end]];
36
+ }
37
+ }
38
+ exports.segment = segment;
39
+ //# sourceMappingURL=segment.js.map
@@ -0,0 +1,3 @@
1
+ import { Range, Segment } from './types';
2
+ export declare function overwriteSource<T extends Segment<any>>(s: T[], sourceLoc: number | Range, ...newSegments: T[]): T[];
3
+ export declare function overwriteSource<T extends Segment<any>>(s: T[], source: string, sourceLoc: number | Range, ...newSegments: T[]): T[];
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.overwriteSource = void 0;
4
+ const basic_1 = require("./basic");
5
+ function searchSource(s, ...args) {
6
+ const source = args.length >= 2 ? args[0] : undefined;
7
+ const sourceLoc = args.length >= 2 ? args[1] : args[0];
8
+ let _offset = 0;
9
+ let result;
10
+ for (const segment of s) {
11
+ if (typeof segment === 'string') {
12
+ _offset += segment.length;
13
+ continue;
14
+ }
15
+ if (segment[1] === source) {
16
+ const segmentStart = typeof segment[2] === 'number' ? segment[2] : segment[2][0];
17
+ const segmentEnd = typeof segment[2] === 'number' ? segment[2] + segment[0].length : segment[2][1];
18
+ if (sourceLoc >= segmentStart && sourceLoc <= segmentEnd) {
19
+ result = _offset + (sourceLoc - segmentStart);
20
+ break;
21
+ }
22
+ }
23
+ _offset += segment[0].length;
24
+ }
25
+ if (result === undefined) {
26
+ throw new Error(`Source index not found, source: ${source}, index: ${sourceLoc}`);
27
+ }
28
+ return result;
29
+ }
30
+ function overwriteSource(s, ...args) {
31
+ let loc;
32
+ let newSegments;
33
+ if (typeof args[0] === 'string') {
34
+ const source = args[0];
35
+ const sourceLoc = args[1];
36
+ loc = typeof sourceLoc === 'number'
37
+ ? searchSource(s, source, sourceLoc)
38
+ : [searchSource(s, source, sourceLoc[0]), searchSource(s, source, sourceLoc[1])];
39
+ newSegments = args.slice(2);
40
+ }
41
+ else {
42
+ const sourceLoc = args[0];
43
+ loc = typeof sourceLoc === 'number'
44
+ ? searchSource(s, sourceLoc)
45
+ : [searchSource(s, sourceLoc[0]), searchSource(s, sourceLoc[1])];
46
+ newSegments = args.slice(1);
47
+ }
48
+ return (0, basic_1.overwrite)(s, loc, ...newSegments);
49
+ }
50
+ exports.overwriteSource = overwriteSource;
51
+ //# sourceMappingURL=sourceBased.js.map
@@ -0,0 +1,2 @@
1
+ import type { Segment } from './types';
2
+ export declare function toString<T extends Segment<any>>(segments: T[]): string;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toString = void 0;
4
+ function toString(segments) {
5
+ return segments.map(s => typeof s === 'string' ? s : s[0]).join('');
6
+ }
7
+ exports.toString = toString;
8
+ //# sourceMappingURL=toString.js.map
package/out/track.d.ts CHANGED
@@ -2,4 +2,4 @@ import { Segment, StackNode } from "./types";
2
2
  export declare function setTracking(value: boolean): void;
3
3
  export declare function offsetStack(): void;
4
4
  export declare function resetOffsetStack(): void;
5
- export declare function track<T extends Segment<any>[]>(segments: T): [T, StackNode[]];
5
+ export declare function track<T extends Segment<any>[]>(segments: T, stacks?: StackNode[]): [T, StackNode[]];
package/out/track.js CHANGED
@@ -15,8 +15,7 @@ function resetOffsetStack() {
15
15
  stackOffset--;
16
16
  }
17
17
  exports.resetOffsetStack = resetOffsetStack;
18
- function track(segments) {
19
- const stacks = [];
18
+ function track(segments, stacks = []) {
20
19
  return [
21
20
  new Proxy(segments, {
22
21
  get(target, prop, receiver) {
@@ -77,29 +76,36 @@ function track(segments) {
77
76
  if (deleteCount === undefined) {
78
77
  deleteCount = segments.length - start;
79
78
  }
80
- let remainDeleteCount = deleteCount;
81
- let stacksDeleteStart;
82
- let stacksDeleteLength = 0;
83
- let stackEnd = 0;
79
+ let _stackStart = 0;
80
+ let operateIndex;
84
81
  for (let i = 0; i < stacks.length; i++) {
85
82
  const stack = stacks[i];
86
- const stackStart = stackEnd;
87
- stackEnd = stackStart + stack.length;
88
- while (start >= stackStart && start < stackEnd && remainDeleteCount && stack.length) {
89
- stack.length--;
90
- remainDeleteCount--;
91
- stackEnd--;
83
+ const stackStart = _stackStart;
84
+ const stackEnd = stackStart + stack.length;
85
+ _stackStart = stackEnd;
86
+ if (start >= stackStart) {
87
+ operateIndex = i + 1;
88
+ const originalLength = stack.length;
89
+ stack.length = start - stackStart;
90
+ stacks.splice(operateIndex, 0, { stack: stack.stack, length: originalLength - stack.length });
91
+ break;
92
92
  }
93
- if (!stack.length) {
94
- stacksDeleteStart !== null && stacksDeleteStart !== void 0 ? stacksDeleteStart : (stacksDeleteStart = i);
95
- stacksDeleteLength++;
93
+ }
94
+ if (operateIndex === undefined) {
95
+ throw new Error('Invalid splice operation');
96
+ }
97
+ let _deleteCount = deleteCount;
98
+ for (let i = operateIndex; i < stacks.length; i++) {
99
+ const stack = stacks[i];
100
+ while (_deleteCount > 0 && stack.length > 0) {
101
+ stack.length--;
102
+ _deleteCount--;
96
103
  }
97
- if (remainDeleteCount <= 0)
104
+ if (_deleteCount === 0) {
98
105
  break;
106
+ }
99
107
  }
100
- if (stacksDeleteStart !== undefined) {
101
- stacks.splice(stacksDeleteStart, stacksDeleteLength);
102
- }
108
+ stacks.splice(operateIndex, 0, { stack: getStack(), length: items.length });
103
109
  return segments.splice(start, deleteCount, ...items);
104
110
  }
105
111
  function sort(compareFn) {
package/out/types.d.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  declare const NO_DATA_SYMBOL: unique symbol;
2
2
  export type Segment<T = typeof NO_DATA_SYMBOL> = string | (T extends typeof NO_DATA_SYMBOL ? [
3
- string,
4
- string | undefined,
5
- number | [number, number]
3
+ text: string,
4
+ source: string | undefined,
5
+ sourceOffset: number
6
6
  ] : [
7
- string,
8
- string | undefined,
9
- number | [number, number],
10
- T
7
+ text: string,
8
+ source: string | undefined,
9
+ sourceOffset: number,
10
+ data: T
11
11
  ]);
12
12
  export interface StackNode {
13
13
  length: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "muggle-string",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "main": "out/index.js",
5
5
  "license": "MIT",
6
6
  "files": [