@morlay/session-rdb 0.0.19 → 0.0.21-alpha.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/README.md +59 -31
- package/dist/artifact.d.mts +25 -65
- package/dist/artifact.mjs +3 -3
- package/dist/{schema-DPcuEh_a.d.mts → backend-DpdtxYpz.d.mts} +360 -107
- package/dist/branch-5JzX9rUq.mjs +390 -0
- package/dist/deletion.d.mts +7 -0
- package/dist/deletion.mjs +2 -0
- package/dist/dist-vIVO6bA-.mjs +1524 -0
- package/dist/import.d.mts +4 -4
- package/dist/import.mjs +214 -1
- package/dist/index.d.mts +2 -3
- package/dist/index.mjs +4 -1630
- package/dist/{log-DO69NQnn.mjs → log-CnYct2Dv.mjs} +37 -82
- package/dist/{sqlite-DYExtbLo.mjs → sqlite-fpvm5Dzs.mjs} +205 -75
- package/dist/src-CWTWV7vx.mjs +1904 -0
- package/dist/storage.d.mts +14 -5
- package/dist/storage.mjs +2 -2
- package/dist/testing.d.mts +2 -26
- package/dist/testing.mjs +10504 -9614
- package/drizzle/postgres/20260918120000_v3_event_usage/migration.sql +14 -0
- package/drizzle/postgres/20260918120000_v3_event_usage/snapshot.json +1309 -0
- package/drizzle/sqlite/20260918120000_v3_event_usage/migration.sql +14 -0
- package/drizzle/sqlite/20260918120000_v3_event_usage/snapshot.json +1031 -0
- package/package.json +29 -30
- package/src/adapters/to-postgres.ts +1 -3
- package/src/adapters/to-sqlite.ts +0 -2
- package/src/adapters/types.ts +0 -3
- package/src/artifact.ts +0 -2
- package/src/backend.ts +31 -2
- package/src/branch.ts +223 -135
- package/src/deletion.ts +87 -0
- package/src/drizzle/postgres-v2.ts +0 -1
- package/src/drizzle/postgres-v3.ts +0 -1
- package/src/drizzle/sqlite-v2.ts +0 -1
- package/src/drizzle/sqlite-v3.ts +0 -1
- package/src/entities/v2/session-events.ts +0 -1
- package/src/entities/v3/event-usage.ts +25 -0
- package/src/entities/v3/events.ts +1 -3
- package/src/entities/v3/index.ts +4 -0
- package/src/entities/v3/session-events.ts +1 -2
- package/src/entities/v3/session-projcache-rows.ts +0 -8
- package/src/entities/v3/sessions.ts +3 -3
- package/src/entities/v3/storage-units.ts +0 -1
- package/src/entities/v3/workspace-sessions.ts +0 -5
- package/src/entities/v3/workspace-state.ts +0 -6
- package/src/entities/v3/workspaces.ts +0 -5
- package/src/export.ts +103 -0
- package/src/gc.ts +76 -0
- package/src/import-storages.ts +4 -37
- package/src/import.ts +54 -31
- package/src/index.ts +150 -114
- package/src/legacy.ts +4 -42
- package/src/log.ts +63 -106
- package/src/postgres.ts +249 -22
- package/src/schema.ts +6 -6
- package/src/session-query.ts +0 -4
- package/src/sqlite.ts +231 -55
- package/src/storage-takeover/index.ts +2 -28
- package/src/storage-takeover/projection-cache.ts +30 -134
- package/src/storage-takeover/repository.ts +20 -59
- package/src/storage-takeover/storage-backend.ts +3 -33
- package/src/storage-takeover/types.ts +14 -56
- package/src/storage.ts +0 -2
- package/src/testing/contract.ts +19 -50
- package/src/testing/coordinator-contract.ts +10 -25
- package/src/testing.ts +2 -2
- package/src/usage.ts +191 -0
- package/dist/import-Bc2QQa5G.mjs +0 -473
- package/dist/index-CCcK9tia.d.mts +0 -270
- package/dist/magic-string.es-BgJoa-3K.mjs +0 -1017
|
@@ -0,0 +1,1524 @@
|
|
|
1
|
+
//#region ../../../node_modules/.pnpm/@jridgewell+sourcemap-codec@1.6.0/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.mjs
|
|
2
|
+
var comma = ",".charCodeAt(0);
|
|
3
|
+
var semicolon = ";".charCodeAt(0);
|
|
4
|
+
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
5
|
+
var intToChar$1 = /* @__PURE__ */ new Uint8Array(64);
|
|
6
|
+
var charToInt = /* @__PURE__ */ new Uint8Array(128);
|
|
7
|
+
for (let i = 0; i < chars.length; i++) {
|
|
8
|
+
const c = chars.charCodeAt(i);
|
|
9
|
+
intToChar$1[i] = c;
|
|
10
|
+
charToInt[c] = i;
|
|
11
|
+
}
|
|
12
|
+
function encodeInteger(builder, num) {
|
|
13
|
+
do {
|
|
14
|
+
let clamped = num & 31;
|
|
15
|
+
num >>>= 5;
|
|
16
|
+
if (num > 0) clamped |= 32;
|
|
17
|
+
builder.write(intToChar$1[clamped]);
|
|
18
|
+
} while (num > 0);
|
|
19
|
+
}
|
|
20
|
+
function encodeSign(num) {
|
|
21
|
+
return num < 0 ? -num << 1 | 1 : num << 1;
|
|
22
|
+
}
|
|
23
|
+
var bufLength = 16384;
|
|
24
|
+
var td = typeof TextDecoder !== "undefined" ? /* @__PURE__ */ new TextDecoder() : typeof Buffer !== "undefined" ? { decode(buf) {
|
|
25
|
+
return Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength).toString();
|
|
26
|
+
} } : { decode(buf) {
|
|
27
|
+
let out = "";
|
|
28
|
+
for (let i = 0; i < buf.length; i++) out += String.fromCharCode(buf[i]);
|
|
29
|
+
return out;
|
|
30
|
+
} };
|
|
31
|
+
var StringWriter = class {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.pos = 0;
|
|
34
|
+
this.out = "";
|
|
35
|
+
this.buffer = new Uint8Array(bufLength);
|
|
36
|
+
}
|
|
37
|
+
write(v) {
|
|
38
|
+
const { buffer } = this;
|
|
39
|
+
buffer[this.pos++] = v;
|
|
40
|
+
if (this.pos === bufLength) {
|
|
41
|
+
this.out += td.decode(buffer);
|
|
42
|
+
this.pos = 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
flush() {
|
|
46
|
+
const { buffer, out, pos } = this;
|
|
47
|
+
return pos > 0 ? out + td.decode(buffer.subarray(0, pos)) : out;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
function encodeRangeMappings(decoded) {
|
|
51
|
+
if (decoded.length === 0) return "";
|
|
52
|
+
const writer = new StringWriter();
|
|
53
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
54
|
+
const indices = decoded[i];
|
|
55
|
+
if (i > 0) writer.write(semicolon);
|
|
56
|
+
let index = 0;
|
|
57
|
+
for (let j = 0; j < indices.length; j++) {
|
|
58
|
+
const offset = indices[j];
|
|
59
|
+
encodeInteger(writer, offset - index);
|
|
60
|
+
index = offset;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return writer.flush();
|
|
64
|
+
}
|
|
65
|
+
function encode(decoded) {
|
|
66
|
+
const writer = new StringWriter();
|
|
67
|
+
let sourcesIndex = 0;
|
|
68
|
+
let sourceLine = 0;
|
|
69
|
+
let sourceColumn = 0;
|
|
70
|
+
let namesIndex = 0;
|
|
71
|
+
for (let i = 0; i < decoded.length; i++) {
|
|
72
|
+
const line = decoded[i];
|
|
73
|
+
if (i > 0) writer.write(semicolon);
|
|
74
|
+
if (line.length === 0) continue;
|
|
75
|
+
let genColumn = 0;
|
|
76
|
+
for (let j = 0; j < line.length; j++) {
|
|
77
|
+
const segment = line[j];
|
|
78
|
+
if (j > 0) writer.write(comma);
|
|
79
|
+
encodeInteger(writer, encodeSign(segment[0] - genColumn));
|
|
80
|
+
genColumn = segment[0];
|
|
81
|
+
if (segment.length === 1) continue;
|
|
82
|
+
encodeInteger(writer, encodeSign(segment[1] - sourcesIndex));
|
|
83
|
+
encodeInteger(writer, encodeSign(segment[2] - sourceLine));
|
|
84
|
+
encodeInteger(writer, encodeSign(segment[3] - sourceColumn));
|
|
85
|
+
sourcesIndex = segment[1];
|
|
86
|
+
sourceLine = segment[2];
|
|
87
|
+
sourceColumn = segment[3];
|
|
88
|
+
if (segment.length === 4) continue;
|
|
89
|
+
encodeInteger(writer, encodeSign(segment[4] - namesIndex));
|
|
90
|
+
namesIndex = segment[4];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return writer.flush();
|
|
94
|
+
}
|
|
95
|
+
//#endregion
|
|
96
|
+
//#region ../../../node_modules/.pnpm/magic-string@1.4.1/node_modules/magic-string/dist/index.mjs
|
|
97
|
+
var BitSet = class BitSet {
|
|
98
|
+
constructor(arg) {
|
|
99
|
+
this.bits = arg instanceof BitSet ? arg.bits.slice() : [];
|
|
100
|
+
}
|
|
101
|
+
add(n) {
|
|
102
|
+
this.bits[n >> 5] |= 1 << (n & 31);
|
|
103
|
+
}
|
|
104
|
+
has(n) {
|
|
105
|
+
return !!(this.bits[n >> 5] & 1 << (n & 31));
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
var Chunk = class Chunk {
|
|
109
|
+
constructor(start, end, content) {
|
|
110
|
+
this.start = start;
|
|
111
|
+
this.end = end;
|
|
112
|
+
this.original = content;
|
|
113
|
+
this.intro = "";
|
|
114
|
+
this.outro = "";
|
|
115
|
+
this.content = content;
|
|
116
|
+
this.storeName = false;
|
|
117
|
+
this.edited = false;
|
|
118
|
+
this.previous = null;
|
|
119
|
+
this.next = null;
|
|
120
|
+
}
|
|
121
|
+
appendLeft(content) {
|
|
122
|
+
this.outro += content;
|
|
123
|
+
}
|
|
124
|
+
appendRight(content) {
|
|
125
|
+
this.intro = this.intro + content;
|
|
126
|
+
}
|
|
127
|
+
clone() {
|
|
128
|
+
const chunk = new Chunk(this.start, this.end, this.original);
|
|
129
|
+
chunk.intro = this.intro;
|
|
130
|
+
chunk.outro = this.outro;
|
|
131
|
+
chunk.content = this.content;
|
|
132
|
+
chunk.storeName = this.storeName;
|
|
133
|
+
chunk.edited = this.edited;
|
|
134
|
+
return chunk;
|
|
135
|
+
}
|
|
136
|
+
contains(index) {
|
|
137
|
+
return this.start < index && index < this.end;
|
|
138
|
+
}
|
|
139
|
+
eachNext(fn) {
|
|
140
|
+
fn(this);
|
|
141
|
+
let chunk = this.next;
|
|
142
|
+
while (chunk) {
|
|
143
|
+
fn(chunk);
|
|
144
|
+
chunk = chunk.next;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
eachPrevious(fn) {
|
|
148
|
+
fn(this);
|
|
149
|
+
let chunk = this.previous;
|
|
150
|
+
while (chunk) {
|
|
151
|
+
fn(chunk);
|
|
152
|
+
chunk = chunk.previous;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
edit(content, storeName, contentOnly) {
|
|
156
|
+
this.content = content;
|
|
157
|
+
if (!contentOnly) {
|
|
158
|
+
this.intro = "";
|
|
159
|
+
this.outro = "";
|
|
160
|
+
}
|
|
161
|
+
this.storeName = storeName;
|
|
162
|
+
this.edited = true;
|
|
163
|
+
return this;
|
|
164
|
+
}
|
|
165
|
+
prependLeft(content) {
|
|
166
|
+
this.outro = content + this.outro;
|
|
167
|
+
}
|
|
168
|
+
prependRight(content) {
|
|
169
|
+
this.intro = content + this.intro;
|
|
170
|
+
}
|
|
171
|
+
reset() {
|
|
172
|
+
this.intro = "";
|
|
173
|
+
this.outro = "";
|
|
174
|
+
if (this.edited) {
|
|
175
|
+
this.content = this.original;
|
|
176
|
+
this.storeName = false;
|
|
177
|
+
this.edited = false;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
split(index) {
|
|
181
|
+
const sliceIndex = index - this.start;
|
|
182
|
+
const originalBefore = this.original.slice(0, sliceIndex);
|
|
183
|
+
const originalAfter = this.original.slice(sliceIndex);
|
|
184
|
+
this.original = originalBefore;
|
|
185
|
+
const newChunk = new Chunk(index, this.end, originalAfter);
|
|
186
|
+
newChunk.outro = this.outro;
|
|
187
|
+
this.outro = "";
|
|
188
|
+
this.end = index;
|
|
189
|
+
if (this.edited) {
|
|
190
|
+
newChunk.edit("", false);
|
|
191
|
+
this.content = "";
|
|
192
|
+
} else this.content = originalBefore;
|
|
193
|
+
newChunk.next = this.next;
|
|
194
|
+
if (newChunk.next) newChunk.next.previous = newChunk;
|
|
195
|
+
newChunk.previous = this;
|
|
196
|
+
this.next = newChunk;
|
|
197
|
+
return newChunk;
|
|
198
|
+
}
|
|
199
|
+
toString() {
|
|
200
|
+
return this.intro + this.content + this.outro;
|
|
201
|
+
}
|
|
202
|
+
trimEnd(rx) {
|
|
203
|
+
this.outro = this.outro.replace(rx, "");
|
|
204
|
+
if (this.outro.length) return true;
|
|
205
|
+
const trimmed = this.content.replace(rx, "");
|
|
206
|
+
if (trimmed.length) {
|
|
207
|
+
if (trimmed !== this.content) {
|
|
208
|
+
if (this.edited) this.edit(trimmed, this.storeName, true);
|
|
209
|
+
else this.split(this.start + trimmed.length).edit("", void 0, true);
|
|
210
|
+
}
|
|
211
|
+
return true;
|
|
212
|
+
} else {
|
|
213
|
+
this.edit("", void 0, true);
|
|
214
|
+
this.intro = this.intro.replace(rx, "");
|
|
215
|
+
if (this.intro.length) return true;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
trimStart(rx) {
|
|
219
|
+
this.intro = this.intro.replace(rx, "");
|
|
220
|
+
if (this.intro.length) return true;
|
|
221
|
+
const trimmed = this.content.replace(rx, "");
|
|
222
|
+
if (trimmed.length) {
|
|
223
|
+
if (trimmed !== this.content) {
|
|
224
|
+
if (this.edited) this.edit(trimmed, this.storeName, true);
|
|
225
|
+
else {
|
|
226
|
+
this.split(this.end - trimmed.length);
|
|
227
|
+
this.edit("", void 0, true);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return true;
|
|
231
|
+
} else {
|
|
232
|
+
this.edit("", void 0, true);
|
|
233
|
+
this.outro = this.outro.replace(rx, "");
|
|
234
|
+
if (this.outro.length) return true;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* The single error type thrown by MagicString.
|
|
240
|
+
*
|
|
241
|
+
* Every message is prefixed with `[MagicString]` so its source is obvious at a
|
|
242
|
+
* glance, and is kept short and consistent in tone.
|
|
243
|
+
*/
|
|
244
|
+
var MagicStringError = class extends Error {
|
|
245
|
+
name = "MagicStringError";
|
|
246
|
+
constructor(message, options) {
|
|
247
|
+
super(`[MagicString] ${message}`, options);
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
function getBtoa() {
|
|
251
|
+
/* v8 ignore next -- environment fallback, unreachable when `btoa` is present */
|
|
252
|
+
if (typeof globalThis !== "undefined" && typeof globalThis.btoa === "function") return (str) => globalThis.btoa(unescape(encodeURIComponent(str)));
|
|
253
|
+
const buffer = globalThis["Buffer"];
|
|
254
|
+
if (buffer) return (str) => buffer.from(str, "utf-8").toString("base64");
|
|
255
|
+
return () => {
|
|
256
|
+
throw new MagicStringError("unsupported environment: `btoa` or `Buffer` is required");
|
|
257
|
+
};
|
|
258
|
+
/* v8 ignore stop */
|
|
259
|
+
}
|
|
260
|
+
const btoa = /* #__PURE__ */ getBtoa();
|
|
261
|
+
var SourceMap = class {
|
|
262
|
+
constructor(properties) {
|
|
263
|
+
this.version = 3;
|
|
264
|
+
this.file = properties.file;
|
|
265
|
+
this.sources = properties.sources;
|
|
266
|
+
this.sourcesContent = properties.sourcesContent;
|
|
267
|
+
this.names = properties.names;
|
|
268
|
+
this.mappings = typeof properties.mappings === "string" ? properties.mappings : encode(properties.mappings);
|
|
269
|
+
if (typeof properties.x_google_ignoreList !== "undefined") this.x_google_ignoreList = properties.x_google_ignoreList;
|
|
270
|
+
if (typeof properties.debugId !== "undefined") this.debugId = properties.debugId;
|
|
271
|
+
if (typeof properties.rangeMappings !== "undefined") {
|
|
272
|
+
let shouldOutputRangeMapping = false;
|
|
273
|
+
for (const line of properties.rangeMappings) if (line.length !== 0) {
|
|
274
|
+
shouldOutputRangeMapping = true;
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
if (shouldOutputRangeMapping) this.rangeMappings = encodeRangeMappings(properties.rangeMappings);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Returns the equivalent of `JSON.stringify(map)`
|
|
282
|
+
*/
|
|
283
|
+
toString() {
|
|
284
|
+
return JSON.stringify(this);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Returns a DataURI containing the sourcemap. Useful for doing this sort of thing:
|
|
288
|
+
* `generateMap(options?: SourceMapOptions): SourceMap;`
|
|
289
|
+
*/
|
|
290
|
+
toUrl() {
|
|
291
|
+
return `data:application/json;charset=utf-8;base64,${btoa(this.toString())}`;
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
function getLocator(source) {
|
|
295
|
+
const lineOffsets = [0];
|
|
296
|
+
for (let i = source.indexOf("\n"); i !== -1; i = source.indexOf("\n", i + 1)) lineOffsets.push(i + 1);
|
|
297
|
+
return function locate(index) {
|
|
298
|
+
let i = 0;
|
|
299
|
+
let j = lineOffsets.length;
|
|
300
|
+
while (i < j) {
|
|
301
|
+
const m = i + j >> 1;
|
|
302
|
+
if (index < lineOffsets[m]) j = m;
|
|
303
|
+
else i = m + 1;
|
|
304
|
+
}
|
|
305
|
+
const line = i - 1;
|
|
306
|
+
return {
|
|
307
|
+
line,
|
|
308
|
+
column: index - lineOffsets[line]
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
function getRelativePath(from, to) {
|
|
313
|
+
const fromParts = from.split(/[/\\]/);
|
|
314
|
+
const toParts = to.split(/[/\\]/);
|
|
315
|
+
fromParts.pop();
|
|
316
|
+
while (fromParts[0] === toParts[0]) {
|
|
317
|
+
fromParts.shift();
|
|
318
|
+
toParts.shift();
|
|
319
|
+
}
|
|
320
|
+
if (fromParts.length) {
|
|
321
|
+
let i = fromParts.length;
|
|
322
|
+
while (i--) fromParts[i] = "..";
|
|
323
|
+
}
|
|
324
|
+
return fromParts.concat(toParts).join("/");
|
|
325
|
+
}
|
|
326
|
+
function guessIndent(code) {
|
|
327
|
+
const lines = code.split("\n");
|
|
328
|
+
const tabbed = lines.filter((line) => /^\t+/.test(line));
|
|
329
|
+
const spaced = lines.filter((line) => /^ {2,}/.test(line));
|
|
330
|
+
if (tabbed.length === 0 && spaced.length === 0) return null;
|
|
331
|
+
if (tabbed.length >= spaced.length) return " ";
|
|
332
|
+
const min = spaced.reduce((previous, current) => {
|
|
333
|
+
const numSpaces = /^ +/.exec(current)[0].length;
|
|
334
|
+
return Math.min(numSpaces, previous);
|
|
335
|
+
}, Infinity);
|
|
336
|
+
return " ".repeat(min);
|
|
337
|
+
}
|
|
338
|
+
const toString = Object.prototype.toString;
|
|
339
|
+
function isObject(thing) {
|
|
340
|
+
return toString.call(thing) === "[object Object]";
|
|
341
|
+
}
|
|
342
|
+
const BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
343
|
+
const intToChar = /* #__PURE__ */ (() => {
|
|
344
|
+
const chars = /* @__PURE__ */ new Uint8Array(64);
|
|
345
|
+
for (let i = 0; i < 64; i++) chars[i] = BASE64_CHARS.charCodeAt(i);
|
|
346
|
+
return chars;
|
|
347
|
+
})();
|
|
348
|
+
const COMMA = 44;
|
|
349
|
+
const SEMICOLON = 59;
|
|
350
|
+
const BUFFER_SIZE = 16384;
|
|
351
|
+
const FLUSH_THRESHOLD = 16348;
|
|
352
|
+
const scratch = /* #__PURE__ */ new Uint8Array(BUFFER_SIZE);
|
|
353
|
+
function writeVlq(pos, num) {
|
|
354
|
+
num = num < 0 ? -num << 1 | 1 : num << 1;
|
|
355
|
+
do {
|
|
356
|
+
let clamped = num & 31;
|
|
357
|
+
num >>>= 5;
|
|
358
|
+
if (num > 0) clamped |= 32;
|
|
359
|
+
scratch[pos++] = intToChar[clamped];
|
|
360
|
+
} while (num > 0);
|
|
361
|
+
return pos;
|
|
362
|
+
}
|
|
363
|
+
const decoder = /* #__PURE__ */ new TextDecoder();
|
|
364
|
+
var MappingsEncoder = class {
|
|
365
|
+
constructor() {
|
|
366
|
+
this.out = "";
|
|
367
|
+
this.pos = 0;
|
|
368
|
+
this.lines = [];
|
|
369
|
+
this.buffered = 0;
|
|
370
|
+
this.needsComma = false;
|
|
371
|
+
this.prevGenColumn = 0;
|
|
372
|
+
this.prevSourceIndex = 0;
|
|
373
|
+
this.prevSourceLine = 0;
|
|
374
|
+
this.prevSourceColumn = 0;
|
|
375
|
+
this.prevNameIndex = 0;
|
|
376
|
+
}
|
|
377
|
+
endLine(segments) {
|
|
378
|
+
this.lines.push(segments);
|
|
379
|
+
this.buffered += segments.length + 1;
|
|
380
|
+
if (this.buffered >= 4096) this.drain(null);
|
|
381
|
+
}
|
|
382
|
+
segments(segments) {
|
|
383
|
+
this.drain(segments);
|
|
384
|
+
}
|
|
385
|
+
finish(segments) {
|
|
386
|
+
this.drain(segments);
|
|
387
|
+
this.flush();
|
|
388
|
+
return this.out;
|
|
389
|
+
}
|
|
390
|
+
drain(trailing) {
|
|
391
|
+
const lines = this.lines;
|
|
392
|
+
const lineCount = lines.length;
|
|
393
|
+
for (let l = 0; l <= lineCount; l++) {
|
|
394
|
+
const line = l < lineCount ? lines[l] : trailing;
|
|
395
|
+
if (line === null) break;
|
|
396
|
+
for (let i = 0; i < line.length; i++) {
|
|
397
|
+
if (this.pos > FLUSH_THRESHOLD) this.flush();
|
|
398
|
+
const segment = line[i];
|
|
399
|
+
if (this.needsComma) scratch[this.pos++] = COMMA;
|
|
400
|
+
this.needsComma = true;
|
|
401
|
+
this.pos = writeVlq(this.pos, segment[0] - this.prevGenColumn);
|
|
402
|
+
this.prevGenColumn = segment[0];
|
|
403
|
+
this.pos = writeVlq(this.pos, segment[1] - this.prevSourceIndex);
|
|
404
|
+
this.prevSourceIndex = segment[1];
|
|
405
|
+
this.pos = writeVlq(this.pos, segment[2] - this.prevSourceLine);
|
|
406
|
+
this.prevSourceLine = segment[2];
|
|
407
|
+
this.pos = writeVlq(this.pos, segment[3] - this.prevSourceColumn);
|
|
408
|
+
this.prevSourceColumn = segment[3];
|
|
409
|
+
if (segment.length === 5) {
|
|
410
|
+
this.pos = writeVlq(this.pos, segment[4] - this.prevNameIndex);
|
|
411
|
+
this.prevNameIndex = segment[4];
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
if (l < lineCount) {
|
|
415
|
+
if (this.pos > FLUSH_THRESHOLD) this.flush();
|
|
416
|
+
scratch[this.pos++] = SEMICOLON;
|
|
417
|
+
this.needsComma = false;
|
|
418
|
+
this.prevGenColumn = 0;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
lines.length = 0;
|
|
422
|
+
this.buffered = 0;
|
|
423
|
+
this.flush();
|
|
424
|
+
}
|
|
425
|
+
flush() {
|
|
426
|
+
this.out += decoder.decode(scratch.subarray(0, this.pos));
|
|
427
|
+
this.pos = 0;
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
const NEWLINE_CHAR$1 = 10;
|
|
431
|
+
function isWordCode(code) {
|
|
432
|
+
return code >= 97 && code <= 122 || code >= 65 && code <= 90 || code >= 48 && code <= 57 || code === 95;
|
|
433
|
+
}
|
|
434
|
+
var Mappings = class {
|
|
435
|
+
constructor(hires, encoder = null) {
|
|
436
|
+
this.hires = hires;
|
|
437
|
+
this.generatedCodeLine = 0;
|
|
438
|
+
this.generatedCodeColumn = 0;
|
|
439
|
+
this.raw = [];
|
|
440
|
+
this.rawSegments = this.raw[this.generatedCodeLine] = [];
|
|
441
|
+
this.rawRangeMappings = [];
|
|
442
|
+
this.rawRangeMappingsIndices = this.rawRangeMappings[this.generatedCodeLine] = [];
|
|
443
|
+
this.encoder = encoder;
|
|
444
|
+
}
|
|
445
|
+
nextLine() {
|
|
446
|
+
if (this.encoder === null) {
|
|
447
|
+
this.generatedCodeLine += 1;
|
|
448
|
+
this.raw[this.generatedCodeLine] = this.rawSegments = [];
|
|
449
|
+
} else {
|
|
450
|
+
this.encoder.endLine(this.rawSegments);
|
|
451
|
+
this.rawSegments = [];
|
|
452
|
+
this.generatedCodeLine += 1;
|
|
453
|
+
}
|
|
454
|
+
this.generatedCodeColumn = 0;
|
|
455
|
+
this.rawRangeMappings[this.generatedCodeLine] = this.rawRangeMappingsIndices = [];
|
|
456
|
+
}
|
|
457
|
+
addEdit(sourceIndex, content, loc, nameIndex) {
|
|
458
|
+
if (content.length) {
|
|
459
|
+
const contentLengthMinusOne = content.length - 1;
|
|
460
|
+
let contentLineEnd = content.indexOf("\n", 0);
|
|
461
|
+
let previousContentLineEnd = -1;
|
|
462
|
+
while (contentLineEnd >= 0 && contentLengthMinusOne > contentLineEnd) {
|
|
463
|
+
const segment = [
|
|
464
|
+
this.generatedCodeColumn,
|
|
465
|
+
sourceIndex,
|
|
466
|
+
loc.line,
|
|
467
|
+
loc.column
|
|
468
|
+
];
|
|
469
|
+
if (nameIndex >= 0) segment.push(nameIndex);
|
|
470
|
+
this.rawSegments.push(segment);
|
|
471
|
+
this.nextLine();
|
|
472
|
+
previousContentLineEnd = contentLineEnd;
|
|
473
|
+
contentLineEnd = content.indexOf("\n", contentLineEnd + 1);
|
|
474
|
+
}
|
|
475
|
+
const segment = [
|
|
476
|
+
this.generatedCodeColumn,
|
|
477
|
+
sourceIndex,
|
|
478
|
+
loc.line,
|
|
479
|
+
loc.column
|
|
480
|
+
];
|
|
481
|
+
if (nameIndex >= 0) segment.push(nameIndex);
|
|
482
|
+
this.rawSegments.push(segment);
|
|
483
|
+
this.advance(content.slice(previousContentLineEnd + 1));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
addUneditedChunk(sourceIndex, chunk, original, loc, sourcemapLocations) {
|
|
487
|
+
const end = chunk.end;
|
|
488
|
+
let i = chunk.start;
|
|
489
|
+
if (this.hires) {
|
|
490
|
+
const boundary = this.hires === "boundary";
|
|
491
|
+
const experimentalRange = this.hires === "experimental-range";
|
|
492
|
+
const encoder = experimentalRange ? null : this.encoder;
|
|
493
|
+
let charInHiresBoundary = false;
|
|
494
|
+
while (i < end) {
|
|
495
|
+
if (encoder !== null && this.rawSegments.length >= 4096) {
|
|
496
|
+
encoder.segments(this.rawSegments);
|
|
497
|
+
this.rawSegments.length = 0;
|
|
498
|
+
}
|
|
499
|
+
if (experimentalRange && i + 1 >= end) this.rawSegments.push([
|
|
500
|
+
this.generatedCodeColumn,
|
|
501
|
+
sourceIndex,
|
|
502
|
+
loc.line,
|
|
503
|
+
loc.column
|
|
504
|
+
]);
|
|
505
|
+
const code = original.charCodeAt(i);
|
|
506
|
+
if (code === NEWLINE_CHAR$1) {
|
|
507
|
+
loc.line += 1;
|
|
508
|
+
loc.column = 0;
|
|
509
|
+
this.nextLine();
|
|
510
|
+
charInHiresBoundary = false;
|
|
511
|
+
} else {
|
|
512
|
+
if (boundary) {
|
|
513
|
+
if (isWordCode(code)) {
|
|
514
|
+
if (!charInHiresBoundary) {
|
|
515
|
+
this.rawSegments.push([
|
|
516
|
+
this.generatedCodeColumn,
|
|
517
|
+
sourceIndex,
|
|
518
|
+
loc.line,
|
|
519
|
+
loc.column
|
|
520
|
+
]);
|
|
521
|
+
charInHiresBoundary = true;
|
|
522
|
+
}
|
|
523
|
+
} else {
|
|
524
|
+
this.rawSegments.push([
|
|
525
|
+
this.generatedCodeColumn,
|
|
526
|
+
sourceIndex,
|
|
527
|
+
loc.line,
|
|
528
|
+
loc.column
|
|
529
|
+
]);
|
|
530
|
+
charInHiresBoundary = false;
|
|
531
|
+
}
|
|
532
|
+
} else if (experimentalRange) {
|
|
533
|
+
if (i === chunk.start) {
|
|
534
|
+
this.rawRangeMappingsIndices.push(this.rawSegments.length);
|
|
535
|
+
this.rawSegments.push([
|
|
536
|
+
this.generatedCodeColumn,
|
|
537
|
+
sourceIndex,
|
|
538
|
+
loc.line,
|
|
539
|
+
loc.column
|
|
540
|
+
]);
|
|
541
|
+
}
|
|
542
|
+
} else this.rawSegments.push([
|
|
543
|
+
this.generatedCodeColumn,
|
|
544
|
+
sourceIndex,
|
|
545
|
+
loc.line,
|
|
546
|
+
loc.column
|
|
547
|
+
]);
|
|
548
|
+
loc.column += 1;
|
|
549
|
+
this.generatedCodeColumn += 1;
|
|
550
|
+
}
|
|
551
|
+
i += 1;
|
|
552
|
+
}
|
|
553
|
+
} else {
|
|
554
|
+
const bits = sourcemapLocations.bits;
|
|
555
|
+
while (i < end) {
|
|
556
|
+
let newline = original.indexOf("\n", i);
|
|
557
|
+
if (newline === -1 || newline > end) newline = end;
|
|
558
|
+
if (newline > i) {
|
|
559
|
+
this.rawSegments.push([
|
|
560
|
+
this.generatedCodeColumn,
|
|
561
|
+
sourceIndex,
|
|
562
|
+
loc.line,
|
|
563
|
+
loc.column
|
|
564
|
+
]);
|
|
565
|
+
for (let w = i + 1 >> 5, last = newline - 1 >> 5; w <= last; w++) {
|
|
566
|
+
let word = bits[w];
|
|
567
|
+
if (!word) continue;
|
|
568
|
+
const base = w << 5;
|
|
569
|
+
while (word) {
|
|
570
|
+
const lowest = word & -word;
|
|
571
|
+
const index = base + 31 - Math.clz32(lowest);
|
|
572
|
+
if (index > i && index < newline) {
|
|
573
|
+
const offset = index - i;
|
|
574
|
+
this.rawSegments.push([
|
|
575
|
+
this.generatedCodeColumn + offset,
|
|
576
|
+
sourceIndex,
|
|
577
|
+
loc.line,
|
|
578
|
+
loc.column + offset
|
|
579
|
+
]);
|
|
580
|
+
}
|
|
581
|
+
word ^= lowest;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
loc.column += newline - i;
|
|
585
|
+
this.generatedCodeColumn += newline - i;
|
|
586
|
+
}
|
|
587
|
+
if (newline === end) break;
|
|
588
|
+
loc.line += 1;
|
|
589
|
+
loc.column = 0;
|
|
590
|
+
this.nextLine();
|
|
591
|
+
i = newline + 1;
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
advance(str) {
|
|
596
|
+
if (!str) return;
|
|
597
|
+
const lastNewline = str.lastIndexOf("\n");
|
|
598
|
+
for (let i = str.indexOf("\n"); i !== -1; i = str.indexOf("\n", i + 1)) this.nextLine();
|
|
599
|
+
this.generatedCodeColumn += str.length - lastNewline - 1;
|
|
600
|
+
}
|
|
601
|
+
};
|
|
602
|
+
const n = "\n";
|
|
603
|
+
const NEWLINE_CHAR = "\n".charCodeAt(0);
|
|
604
|
+
const CR_CHAR = "\r".charCodeAt(0);
|
|
605
|
+
const warned = {
|
|
606
|
+
insertLeft: false,
|
|
607
|
+
insertRight: false,
|
|
608
|
+
storeName: false
|
|
609
|
+
};
|
|
610
|
+
/**
|
|
611
|
+
* Expands the `$` substitution patterns that `String.prototype.replace` accepts
|
|
612
|
+
* in a string replacement.
|
|
613
|
+
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_a_parameter
|
|
614
|
+
*
|
|
615
|
+
* `captures` holds the capture groups in order, so `captures[0]` is `$1`.
|
|
616
|
+
* `namedCaptures` is `undefined` when the pattern has no named groups, and
|
|
617
|
+
* `$<name>` is then literal text - which is also the case for a string search
|
|
618
|
+
* value, where there are no groups of either kind.
|
|
619
|
+
*/
|
|
620
|
+
function expandReplacement(replacement, matched, position, str, captures, namedCaptures) {
|
|
621
|
+
if (!replacement.includes("$")) return replacement;
|
|
622
|
+
let result = "";
|
|
623
|
+
let index = 0;
|
|
624
|
+
while (index < replacement.length) {
|
|
625
|
+
const dollar = replacement.indexOf("$", index);
|
|
626
|
+
if (dollar === -1) {
|
|
627
|
+
result += replacement.slice(index);
|
|
628
|
+
break;
|
|
629
|
+
}
|
|
630
|
+
result += replacement.slice(index, dollar);
|
|
631
|
+
const char = replacement[dollar + 1];
|
|
632
|
+
let expansion = "$";
|
|
633
|
+
let consumed = 1;
|
|
634
|
+
if (char === "$") consumed = 2;
|
|
635
|
+
else if (char === "&") {
|
|
636
|
+
expansion = matched;
|
|
637
|
+
consumed = 2;
|
|
638
|
+
} else if (char === "`") {
|
|
639
|
+
expansion = str.slice(0, position);
|
|
640
|
+
consumed = 2;
|
|
641
|
+
} else if (char === "'") {
|
|
642
|
+
expansion = str.slice(position + matched.length);
|
|
643
|
+
consumed = 2;
|
|
644
|
+
} else if (char === "<" && namedCaptures !== void 0) {
|
|
645
|
+
const close = replacement.indexOf(">", dollar + 2);
|
|
646
|
+
if (close !== -1) {
|
|
647
|
+
expansion = namedCaptures[replacement.slice(dollar + 2, close)] ?? "";
|
|
648
|
+
consumed = close + 1 - dollar;
|
|
649
|
+
}
|
|
650
|
+
} else if (char >= "0" && char <= "9") {
|
|
651
|
+
const second = replacement[dollar + 2];
|
|
652
|
+
const double = second >= "0" && second <= "9" ? Number(char + second) : NaN;
|
|
653
|
+
const single = Number(char);
|
|
654
|
+
if (double >= 1 && double <= captures.length) {
|
|
655
|
+
expansion = captures[double - 1] ?? "";
|
|
656
|
+
consumed = 3;
|
|
657
|
+
} else if (single >= 1 && single <= captures.length) {
|
|
658
|
+
expansion = captures[single - 1] ?? "";
|
|
659
|
+
consumed = 2;
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
result += expansion;
|
|
663
|
+
index = dollar + consumed;
|
|
664
|
+
}
|
|
665
|
+
return result;
|
|
666
|
+
}
|
|
667
|
+
var MagicString = class MagicString {
|
|
668
|
+
constructor(string, options = {}) {
|
|
669
|
+
const chunk = new Chunk(0, string.length, string);
|
|
670
|
+
Object.defineProperties(this, {
|
|
671
|
+
original: {
|
|
672
|
+
writable: true,
|
|
673
|
+
value: string
|
|
674
|
+
},
|
|
675
|
+
outro: {
|
|
676
|
+
writable: true,
|
|
677
|
+
value: ""
|
|
678
|
+
},
|
|
679
|
+
intro: {
|
|
680
|
+
writable: true,
|
|
681
|
+
value: ""
|
|
682
|
+
},
|
|
683
|
+
firstChunk: {
|
|
684
|
+
writable: true,
|
|
685
|
+
value: chunk
|
|
686
|
+
},
|
|
687
|
+
lastChunk: {
|
|
688
|
+
writable: true,
|
|
689
|
+
value: chunk
|
|
690
|
+
},
|
|
691
|
+
lastSearchedChunk: {
|
|
692
|
+
writable: true,
|
|
693
|
+
value: chunk
|
|
694
|
+
},
|
|
695
|
+
byStart: {
|
|
696
|
+
writable: true,
|
|
697
|
+
value: /* @__PURE__ */ new Map([[0, chunk]])
|
|
698
|
+
},
|
|
699
|
+
byEnd: {
|
|
700
|
+
writable: true,
|
|
701
|
+
value: /* @__PURE__ */ new Map([[string.length, chunk]])
|
|
702
|
+
},
|
|
703
|
+
filename: {
|
|
704
|
+
writable: true,
|
|
705
|
+
value: options.filename
|
|
706
|
+
},
|
|
707
|
+
indentExclusionRanges: {
|
|
708
|
+
writable: true,
|
|
709
|
+
value: options.indentExclusionRanges
|
|
710
|
+
},
|
|
711
|
+
sourcemapLocations: {
|
|
712
|
+
writable: true,
|
|
713
|
+
value: new BitSet()
|
|
714
|
+
},
|
|
715
|
+
storedNames: {
|
|
716
|
+
writable: true,
|
|
717
|
+
value: {}
|
|
718
|
+
},
|
|
719
|
+
indentStr: {
|
|
720
|
+
writable: true,
|
|
721
|
+
value: void 0
|
|
722
|
+
},
|
|
723
|
+
ignoreList: {
|
|
724
|
+
writable: true,
|
|
725
|
+
value: options.ignoreList
|
|
726
|
+
},
|
|
727
|
+
offset: {
|
|
728
|
+
writable: true,
|
|
729
|
+
value: options.offset || 0
|
|
730
|
+
},
|
|
731
|
+
hasMovedChunks: {
|
|
732
|
+
writable: true,
|
|
733
|
+
value: false
|
|
734
|
+
}
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
/**
|
|
738
|
+
* Adds the specified character index (with respect to the original string) to sourcemap mappings, if `hires` is false.
|
|
739
|
+
*/
|
|
740
|
+
addSourcemapLocation(char) {
|
|
741
|
+
this.sourcemapLocations.add(char);
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Appends the specified content to the end of the string.
|
|
745
|
+
*/
|
|
746
|
+
append(content) {
|
|
747
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
748
|
+
this.outro += content;
|
|
749
|
+
return this;
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* Appends the specified content at the index in the original string.
|
|
753
|
+
* If a range *ending* with index is subsequently moved, the insert will be moved with it.
|
|
754
|
+
* See also `s.prependLeft(...)`.
|
|
755
|
+
*/
|
|
756
|
+
appendLeft(index, content) {
|
|
757
|
+
index = index + this.offset;
|
|
758
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
759
|
+
this._split(index);
|
|
760
|
+
const chunk = this.byEnd.get(index);
|
|
761
|
+
if (chunk) chunk.appendLeft(content);
|
|
762
|
+
else this.intro += content;
|
|
763
|
+
return this;
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Appends the specified content at the index in the original string.
|
|
767
|
+
* If a range *starting* with index is subsequently moved, the insert will be moved with it.
|
|
768
|
+
* See also `s.prependRight(...)`.
|
|
769
|
+
*/
|
|
770
|
+
appendRight(index, content) {
|
|
771
|
+
index = index + this.offset;
|
|
772
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
773
|
+
this._split(index);
|
|
774
|
+
const chunk = this.byStart.get(index);
|
|
775
|
+
if (chunk) chunk.appendRight(content);
|
|
776
|
+
else this.outro += content;
|
|
777
|
+
return this;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Does what you'd expect.
|
|
781
|
+
*/
|
|
782
|
+
clone() {
|
|
783
|
+
const cloned = new MagicString(this.original, {
|
|
784
|
+
filename: this.filename,
|
|
785
|
+
ignoreList: this.ignoreList,
|
|
786
|
+
offset: this.offset
|
|
787
|
+
});
|
|
788
|
+
let originalChunk = this.firstChunk;
|
|
789
|
+
let clonedChunk = cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone();
|
|
790
|
+
while (originalChunk) {
|
|
791
|
+
cloned.byStart.set(clonedChunk.start, clonedChunk);
|
|
792
|
+
cloned.byEnd.set(clonedChunk.end, clonedChunk);
|
|
793
|
+
const nextOriginalChunk = originalChunk.next;
|
|
794
|
+
const nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
|
|
795
|
+
if (nextClonedChunk) {
|
|
796
|
+
clonedChunk.next = nextClonedChunk;
|
|
797
|
+
nextClonedChunk.previous = clonedChunk;
|
|
798
|
+
clonedChunk = nextClonedChunk;
|
|
799
|
+
}
|
|
800
|
+
originalChunk = nextOriginalChunk;
|
|
801
|
+
}
|
|
802
|
+
cloned.lastChunk = clonedChunk;
|
|
803
|
+
if (this.indentExclusionRanges) cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
|
|
804
|
+
cloned.sourcemapLocations = new BitSet(this.sourcemapLocations);
|
|
805
|
+
cloned.storedNames = { ...this.storedNames };
|
|
806
|
+
cloned.intro = this.intro;
|
|
807
|
+
cloned.outro = this.outro;
|
|
808
|
+
cloned.hasMovedChunks = this.hasMovedChunks;
|
|
809
|
+
return cloned;
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Generates a sourcemap object with raw mappings in array form, rather than encoded as a string.
|
|
813
|
+
* Useful if you need to manipulate the sourcemap further, but most of the time you will use `generateMap` instead.
|
|
814
|
+
*/
|
|
815
|
+
generateDecodedMap(options) {
|
|
816
|
+
options = options || {};
|
|
817
|
+
const mappings = new Mappings(options.hires);
|
|
818
|
+
const names = this._generateMappings(mappings);
|
|
819
|
+
return {
|
|
820
|
+
...this._mapProperties(options, names),
|
|
821
|
+
mappings: mappings.raw,
|
|
822
|
+
rangeMappings: mappings.rawRangeMappings
|
|
823
|
+
};
|
|
824
|
+
}
|
|
825
|
+
/**
|
|
826
|
+
* Generates a version 3 sourcemap.
|
|
827
|
+
*/
|
|
828
|
+
generateMap(options) {
|
|
829
|
+
options = options || {};
|
|
830
|
+
const encoder = new MappingsEncoder();
|
|
831
|
+
const mappings = new Mappings(options.hires, encoder);
|
|
832
|
+
const names = this._generateMappings(mappings);
|
|
833
|
+
return new SourceMap({
|
|
834
|
+
...this._mapProperties(options, names),
|
|
835
|
+
mappings: encoder.finish(mappings.rawSegments),
|
|
836
|
+
rangeMappings: mappings.rawRangeMappings
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
/** @internal */
|
|
840
|
+
_generateMappings(mappings) {
|
|
841
|
+
const sourceIndex = 0;
|
|
842
|
+
const names = Object.keys(this.storedNames);
|
|
843
|
+
const locate = getLocator(this.original);
|
|
844
|
+
if (this.intro) mappings.advance(this.intro);
|
|
845
|
+
this.firstChunk.eachNext((chunk) => {
|
|
846
|
+
const loc = locate(chunk.start);
|
|
847
|
+
if (chunk.intro.length) mappings.advance(chunk.intro);
|
|
848
|
+
if (chunk.edited) mappings.addEdit(sourceIndex, chunk.content, loc, chunk.storeName ? names.indexOf(chunk.original) : -1);
|
|
849
|
+
else mappings.addUneditedChunk(sourceIndex, chunk, this.original, loc, this.sourcemapLocations);
|
|
850
|
+
if (chunk.outro.length) mappings.advance(chunk.outro);
|
|
851
|
+
});
|
|
852
|
+
if (this.outro) mappings.advance(this.outro);
|
|
853
|
+
return names;
|
|
854
|
+
}
|
|
855
|
+
/** @internal */
|
|
856
|
+
_mapProperties(options, names) {
|
|
857
|
+
return {
|
|
858
|
+
file: options.file ? options.file.split(/[/\\]/).pop() : void 0,
|
|
859
|
+
sources: [options.source ? getRelativePath(options.file || "", options.source) : options.file || ""],
|
|
860
|
+
sourcesContent: options.includeContent ? [this.original] : void 0,
|
|
861
|
+
names,
|
|
862
|
+
x_google_ignoreList: this.ignoreList ? [0] : void 0
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
/** @internal */
|
|
866
|
+
_ensureindentStr() {
|
|
867
|
+
if (this.indentStr === void 0) this.indentStr = guessIndent(this.original);
|
|
868
|
+
}
|
|
869
|
+
/** @internal */
|
|
870
|
+
_getRawIndentString() {
|
|
871
|
+
this._ensureindentStr();
|
|
872
|
+
return this.indentStr;
|
|
873
|
+
}
|
|
874
|
+
getIndentString() {
|
|
875
|
+
this._ensureindentStr();
|
|
876
|
+
return this.indentStr === null ? " " : this.indentStr;
|
|
877
|
+
}
|
|
878
|
+
indent(indentStr, options) {
|
|
879
|
+
const pattern = /^[^\r\n]/gm;
|
|
880
|
+
if (isObject(indentStr)) {
|
|
881
|
+
options = indentStr;
|
|
882
|
+
indentStr = void 0;
|
|
883
|
+
}
|
|
884
|
+
if (indentStr === void 0) {
|
|
885
|
+
this._ensureindentStr();
|
|
886
|
+
indentStr = this.indentStr || " ";
|
|
887
|
+
}
|
|
888
|
+
if (indentStr === "") return this;
|
|
889
|
+
const resolvedIndentStr = indentStr;
|
|
890
|
+
options = options || {};
|
|
891
|
+
const isExcluded = {};
|
|
892
|
+
if (options.exclude) (typeof options.exclude[0] === "number" ? [options.exclude] : options.exclude).forEach((exclusion) => {
|
|
893
|
+
for (let i = exclusion[0]; i < exclusion[1]; i += 1) isExcluded[i] = true;
|
|
894
|
+
});
|
|
895
|
+
let shouldIndentNextCharacter = options.indentStart !== false;
|
|
896
|
+
const indentPiece = (str) => {
|
|
897
|
+
if (str === "") return str;
|
|
898
|
+
const indented = str.replace(pattern, (match, offset) => offset > 0 || shouldIndentNextCharacter ? `${resolvedIndentStr}${match}` : match);
|
|
899
|
+
shouldIndentNextCharacter = str[str.length - 1] === "\n";
|
|
900
|
+
return indented;
|
|
901
|
+
};
|
|
902
|
+
this.intro = indentPiece(this.intro);
|
|
903
|
+
let charIndex = 0;
|
|
904
|
+
let chunk = this.firstChunk;
|
|
905
|
+
const indentAt = (index) => {
|
|
906
|
+
shouldIndentNextCharacter = false;
|
|
907
|
+
if (index === chunk.start) chunk.appendRight(resolvedIndentStr);
|
|
908
|
+
else {
|
|
909
|
+
this._splitChunk(chunk, index);
|
|
910
|
+
chunk = chunk.next;
|
|
911
|
+
chunk.prependRight(resolvedIndentStr);
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
while (chunk) {
|
|
915
|
+
const end = chunk.end;
|
|
916
|
+
if (!isExcluded[chunk.start]) chunk.intro = indentPiece(chunk.intro);
|
|
917
|
+
if (chunk.edited) {
|
|
918
|
+
if (!isExcluded[charIndex]) chunk.content = indentPiece(chunk.content);
|
|
919
|
+
} else if (options.exclude) {
|
|
920
|
+
charIndex = chunk.start;
|
|
921
|
+
while (charIndex < end) {
|
|
922
|
+
if (!isExcluded[charIndex]) {
|
|
923
|
+
const char = this.original.charCodeAt(charIndex);
|
|
924
|
+
if (char === NEWLINE_CHAR) shouldIndentNextCharacter = true;
|
|
925
|
+
else if (char !== CR_CHAR && shouldIndentNextCharacter) indentAt(charIndex);
|
|
926
|
+
}
|
|
927
|
+
charIndex += 1;
|
|
928
|
+
}
|
|
929
|
+
} else {
|
|
930
|
+
charIndex = chunk.start;
|
|
931
|
+
while (charIndex < end) {
|
|
932
|
+
if (!shouldIndentNextCharacter) {
|
|
933
|
+
const nextLine = this.original.indexOf(n, charIndex);
|
|
934
|
+
if (nextLine === -1 || nextLine >= end) break;
|
|
935
|
+
shouldIndentNextCharacter = true;
|
|
936
|
+
charIndex = nextLine + 1;
|
|
937
|
+
continue;
|
|
938
|
+
}
|
|
939
|
+
const char = this.original.charCodeAt(charIndex);
|
|
940
|
+
if (char === NEWLINE_CHAR || char === CR_CHAR) {
|
|
941
|
+
charIndex += 1;
|
|
942
|
+
continue;
|
|
943
|
+
}
|
|
944
|
+
indentAt(charIndex);
|
|
945
|
+
charIndex += 1;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
948
|
+
if (!isExcluded[chunk.end - 1]) chunk.outro = indentPiece(chunk.outro);
|
|
949
|
+
charIndex = chunk.end;
|
|
950
|
+
chunk = chunk.next;
|
|
951
|
+
}
|
|
952
|
+
this.outro = indentPiece(this.outro);
|
|
953
|
+
return this;
|
|
954
|
+
}
|
|
955
|
+
/** @internal */
|
|
956
|
+
insert() {
|
|
957
|
+
throw new MagicStringError("insert() is deprecated, use appendLeft() or prependRight()");
|
|
958
|
+
}
|
|
959
|
+
/** @internal */
|
|
960
|
+
insertLeft(index, content) {
|
|
961
|
+
if (!warned.insertLeft) {
|
|
962
|
+
console.warn("magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead");
|
|
963
|
+
warned.insertLeft = true;
|
|
964
|
+
}
|
|
965
|
+
return this.appendLeft(index, content);
|
|
966
|
+
}
|
|
967
|
+
/** @internal */
|
|
968
|
+
insertRight(index, content) {
|
|
969
|
+
if (!warned.insertRight) {
|
|
970
|
+
console.warn("magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead");
|
|
971
|
+
warned.insertRight = true;
|
|
972
|
+
}
|
|
973
|
+
return this.prependRight(index, content);
|
|
974
|
+
}
|
|
975
|
+
/**
|
|
976
|
+
* Moves the characters from `start` and `end` to `index`.
|
|
977
|
+
*
|
|
978
|
+
* `affinity` controls where the range is anchored at `index`. With the
|
|
979
|
+
* default `'right'`, it is inserted before the content that starts at `index`;
|
|
980
|
+
* with `'left'`, it is inserted after the content that ends at `index`. The
|
|
981
|
+
* two differ only when other content has already been moved to that boundary,
|
|
982
|
+
* mirroring the `appendLeft`/`appendRight` distinction.
|
|
983
|
+
*/
|
|
984
|
+
move(start, end, index, affinity = "right") {
|
|
985
|
+
start = start + this.offset;
|
|
986
|
+
end = end + this.offset;
|
|
987
|
+
index = index + this.offset;
|
|
988
|
+
if (start === end) return this;
|
|
989
|
+
if (index >= start && index <= end) throw new MagicStringError("cannot move a selection inside itself");
|
|
990
|
+
this._split(start);
|
|
991
|
+
this._split(end);
|
|
992
|
+
this._split(index);
|
|
993
|
+
const first = this.byStart.get(start);
|
|
994
|
+
const last = this.byEnd.get(end);
|
|
995
|
+
if (this.hasMovedChunks) {
|
|
996
|
+
let cursor = first;
|
|
997
|
+
while (cursor !== last) {
|
|
998
|
+
cursor = cursor.next;
|
|
999
|
+
if (!cursor || cursor.start < start || cursor.end > end) throw new MagicStringError(`cannot move ${start} to ${end} because an earlier move split that range`);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
const oldLeft = first.previous;
|
|
1003
|
+
const oldRight = last.next;
|
|
1004
|
+
let newLeft;
|
|
1005
|
+
let newRight;
|
|
1006
|
+
if (affinity === "left") {
|
|
1007
|
+
newLeft = this.byEnd.get(index) ?? null;
|
|
1008
|
+
if (!newLeft) {
|
|
1009
|
+
if (first === this.firstChunk) return this;
|
|
1010
|
+
newRight = this.firstChunk;
|
|
1011
|
+
} else {
|
|
1012
|
+
if (newLeft.next === first) return this;
|
|
1013
|
+
newRight = newLeft.next;
|
|
1014
|
+
}
|
|
1015
|
+
} else {
|
|
1016
|
+
newRight = this.byStart.get(index) ?? null;
|
|
1017
|
+
if (!newRight) {
|
|
1018
|
+
if (last === this.lastChunk) return this;
|
|
1019
|
+
newLeft = this.lastChunk;
|
|
1020
|
+
} else {
|
|
1021
|
+
if (newRight.previous === last) return this;
|
|
1022
|
+
newLeft = newRight.previous;
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
if (oldLeft) oldLeft.next = oldRight;
|
|
1026
|
+
if (oldRight) oldRight.previous = oldLeft;
|
|
1027
|
+
if (newLeft) newLeft.next = first;
|
|
1028
|
+
if (newRight) newRight.previous = last;
|
|
1029
|
+
if (!first.previous) this.firstChunk = last.next;
|
|
1030
|
+
if (!last.next) {
|
|
1031
|
+
this.lastChunk = first.previous;
|
|
1032
|
+
this.lastChunk.next = null;
|
|
1033
|
+
}
|
|
1034
|
+
first.previous = newLeft;
|
|
1035
|
+
last.next = newRight || null;
|
|
1036
|
+
if (!newLeft) this.firstChunk = first;
|
|
1037
|
+
if (!newRight) this.lastChunk = last;
|
|
1038
|
+
this.hasMovedChunks = true;
|
|
1039
|
+
return this;
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Replaces the characters from `start` to `end` with `content`, along with the appended/prepended content in
|
|
1043
|
+
* that range. The same restrictions as `s.remove()` apply.
|
|
1044
|
+
*
|
|
1045
|
+
* The fourth argument is optional. It can have a storeName property - if true, the original name will be stored
|
|
1046
|
+
* for later inclusion in a sourcemap's names array - and a contentOnly property which determines whether only
|
|
1047
|
+
* the content is overwritten, or anything that was appended/prepended to the range as well.
|
|
1048
|
+
*
|
|
1049
|
+
* It may be preferred to use `s.update(...)` instead if you wish to avoid overwriting the appended/prepended content.
|
|
1050
|
+
*/
|
|
1051
|
+
overwrite(start, end, content, options) {
|
|
1052
|
+
const optionObject = typeof options === "object" && options ? options : {};
|
|
1053
|
+
return this.update(start, end, content, {
|
|
1054
|
+
...optionObject,
|
|
1055
|
+
overwrite: !optionObject.contentOnly
|
|
1056
|
+
});
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Replaces the characters from `start` to `end` with `content`. The same restrictions as `s.remove()` apply.
|
|
1060
|
+
*
|
|
1061
|
+
* The fourth argument is optional. It can have a storeName property - if true, the original name will be stored
|
|
1062
|
+
* for later inclusion in a sourcemap's names array - and an overwrite property which determines whether only
|
|
1063
|
+
* the content is overwritten, or anything that was appended/prepended to the range as well.
|
|
1064
|
+
*/
|
|
1065
|
+
update(start, end, content, options) {
|
|
1066
|
+
start = start + this.offset;
|
|
1067
|
+
end = end + this.offset;
|
|
1068
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
1069
|
+
if (this.original.length !== 0) {
|
|
1070
|
+
if (start < 0) start = Math.max(0, start + this.original.length);
|
|
1071
|
+
if (end < 0) end = Math.max(0, end + this.original.length);
|
|
1072
|
+
}
|
|
1073
|
+
if (start < 0) throw new MagicStringError(`start ${start} is out of bounds`);
|
|
1074
|
+
if (end > this.original.length) throw new MagicStringError(`end ${end} is out of bounds`);
|
|
1075
|
+
if (start === end) throw new MagicStringError(`cannot overwrite a zero-length range at ${start}, use appendLeft() or prependRight()`);
|
|
1076
|
+
if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
|
|
1077
|
+
this._split(start);
|
|
1078
|
+
this._split(end);
|
|
1079
|
+
if (options === true) {
|
|
1080
|
+
if (!warned.storeName) {
|
|
1081
|
+
console.warn("The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string");
|
|
1082
|
+
warned.storeName = true;
|
|
1083
|
+
}
|
|
1084
|
+
options = { storeName: true };
|
|
1085
|
+
}
|
|
1086
|
+
const optionObject = typeof options === "object" && options ? options : {};
|
|
1087
|
+
const storeName = optionObject.storeName || false;
|
|
1088
|
+
const overwrite = optionObject.overwrite || false;
|
|
1089
|
+
if (storeName) {
|
|
1090
|
+
const original = this.original.slice(start, end);
|
|
1091
|
+
Object.defineProperty(this.storedNames, original, {
|
|
1092
|
+
writable: true,
|
|
1093
|
+
value: true,
|
|
1094
|
+
enumerable: true
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
const first = this.byStart.get(start);
|
|
1098
|
+
const last = this.byEnd.get(end);
|
|
1099
|
+
/* v8 ignore else -- unreachable: a valid start/end always yields a `first` chunk */
|
|
1100
|
+
if (first) {
|
|
1101
|
+
let chunk = first;
|
|
1102
|
+
while (chunk !== last) {
|
|
1103
|
+
if (chunk.next !== this.byStart.get(chunk.end)) throw new MagicStringError("cannot overwrite across a split point");
|
|
1104
|
+
chunk = chunk.next;
|
|
1105
|
+
chunk.edit("", false);
|
|
1106
|
+
}
|
|
1107
|
+
first.edit(content, storeName, !overwrite);
|
|
1108
|
+
} else {
|
|
1109
|
+
const newChunk = new Chunk(start, end, "").edit(content, storeName);
|
|
1110
|
+
last.next = newChunk;
|
|
1111
|
+
newChunk.previous = last;
|
|
1112
|
+
}
|
|
1113
|
+
return this;
|
|
1114
|
+
}
|
|
1115
|
+
/**
|
|
1116
|
+
* Prepends the string with the specified content.
|
|
1117
|
+
*/
|
|
1118
|
+
prepend(content) {
|
|
1119
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
1120
|
+
this.intro = content + this.intro;
|
|
1121
|
+
return this;
|
|
1122
|
+
}
|
|
1123
|
+
/**
|
|
1124
|
+
* Same as `s.appendLeft(...)`, except that the inserted content will go *before* any previous appends or prepends at index
|
|
1125
|
+
*/
|
|
1126
|
+
prependLeft(index, content) {
|
|
1127
|
+
index = index + this.offset;
|
|
1128
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
1129
|
+
this._split(index);
|
|
1130
|
+
const chunk = this.byEnd.get(index);
|
|
1131
|
+
if (chunk) chunk.prependLeft(content);
|
|
1132
|
+
else this.intro = content + this.intro;
|
|
1133
|
+
return this;
|
|
1134
|
+
}
|
|
1135
|
+
/**
|
|
1136
|
+
* Same as `s.appendRight(...)`, except that the inserted content will go *before* any previous appends or prepends at `index`
|
|
1137
|
+
*/
|
|
1138
|
+
prependRight(index, content) {
|
|
1139
|
+
index = index + this.offset;
|
|
1140
|
+
if (typeof content !== "string") throw new MagicStringError(`content must be a string, got ${typeof content}`);
|
|
1141
|
+
this._split(index);
|
|
1142
|
+
const chunk = this.byStart.get(index);
|
|
1143
|
+
if (chunk) chunk.prependRight(content);
|
|
1144
|
+
else this.outro = content + this.outro;
|
|
1145
|
+
return this;
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Removes the characters from `start` to `end` (of the original string, **not** the generated string).
|
|
1149
|
+
* Content appended or prepended at positions strictly inside the range is removed with it, while
|
|
1150
|
+
* content attached at `start` or `end` is preserved — use `s.overwrite(start, end, '')` to remove
|
|
1151
|
+
* the range including its edge inserts.
|
|
1152
|
+
* Removing the same content twice, or making removals that partially overlap, will cause an error.
|
|
1153
|
+
*/
|
|
1154
|
+
remove(start, end) {
|
|
1155
|
+
start = start + this.offset;
|
|
1156
|
+
end = end + this.offset;
|
|
1157
|
+
if (this.original.length !== 0) {
|
|
1158
|
+
if (start < 0) start = Math.max(0, start + this.original.length);
|
|
1159
|
+
if (end < 0) end = Math.max(0, end + this.original.length);
|
|
1160
|
+
}
|
|
1161
|
+
if (start === end) return this;
|
|
1162
|
+
if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
|
|
1163
|
+
if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
|
|
1164
|
+
this._split(start);
|
|
1165
|
+
this._split(end);
|
|
1166
|
+
let chunk = this.byStart.get(start);
|
|
1167
|
+
while (chunk) {
|
|
1168
|
+
if (chunk.start > start) chunk.intro = "";
|
|
1169
|
+
if (chunk.end < end) chunk.outro = "";
|
|
1170
|
+
chunk.edit("", false, true);
|
|
1171
|
+
chunk = end > chunk.end ? this.byStart.get(chunk.end) : null;
|
|
1172
|
+
}
|
|
1173
|
+
return this;
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Reset the modified characters from `start` to `end` (of the original string, **not** the generated string).
|
|
1177
|
+
*/
|
|
1178
|
+
reset(start, end) {
|
|
1179
|
+
start = start + this.offset;
|
|
1180
|
+
end = end + this.offset;
|
|
1181
|
+
if (this.original.length !== 0) {
|
|
1182
|
+
if (start < 0) start = Math.max(0, start + this.original.length);
|
|
1183
|
+
if (end < 0) end = Math.max(0, end + this.original.length);
|
|
1184
|
+
}
|
|
1185
|
+
if (start === end) return this;
|
|
1186
|
+
if (start < 0 || end > this.original.length) throw new MagicStringError(`range ${start}–${end} is out of bounds`);
|
|
1187
|
+
if (start > end) throw new MagicStringError(`end must be greater than start (start: ${start}, end: ${end})`);
|
|
1188
|
+
this._split(start);
|
|
1189
|
+
this._split(end);
|
|
1190
|
+
let chunk = this.byStart.get(start);
|
|
1191
|
+
while (chunk) {
|
|
1192
|
+
chunk.reset();
|
|
1193
|
+
chunk = end > chunk.end ? this.byStart.get(chunk.end) : null;
|
|
1194
|
+
}
|
|
1195
|
+
return this;
|
|
1196
|
+
}
|
|
1197
|
+
lastChar() {
|
|
1198
|
+
if (this.outro.length) return this.outro[this.outro.length - 1];
|
|
1199
|
+
let chunk = this.lastChunk;
|
|
1200
|
+
while (chunk) {
|
|
1201
|
+
if (chunk.outro.length) return chunk.outro[chunk.outro.length - 1];
|
|
1202
|
+
if (chunk.content.length) return chunk.content[chunk.content.length - 1];
|
|
1203
|
+
if (chunk.intro.length) return chunk.intro[chunk.intro.length - 1];
|
|
1204
|
+
chunk = chunk.previous;
|
|
1205
|
+
}
|
|
1206
|
+
if (this.intro.length) return this.intro[this.intro.length - 1];
|
|
1207
|
+
return "";
|
|
1208
|
+
}
|
|
1209
|
+
lastLine() {
|
|
1210
|
+
let lineIndex = this.outro.lastIndexOf(n);
|
|
1211
|
+
if (lineIndex !== -1) return this.outro.substr(lineIndex + 1);
|
|
1212
|
+
let lineStr = this.outro;
|
|
1213
|
+
let chunk = this.lastChunk;
|
|
1214
|
+
while (chunk) {
|
|
1215
|
+
if (chunk.outro.length > 0) {
|
|
1216
|
+
lineIndex = chunk.outro.lastIndexOf(n);
|
|
1217
|
+
if (lineIndex !== -1) return chunk.outro.substr(lineIndex + 1) + lineStr;
|
|
1218
|
+
lineStr = chunk.outro + lineStr;
|
|
1219
|
+
}
|
|
1220
|
+
if (chunk.content.length > 0) {
|
|
1221
|
+
lineIndex = chunk.content.lastIndexOf(n);
|
|
1222
|
+
if (lineIndex !== -1) return chunk.content.substr(lineIndex + 1) + lineStr;
|
|
1223
|
+
lineStr = chunk.content + lineStr;
|
|
1224
|
+
}
|
|
1225
|
+
if (chunk.intro.length > 0) {
|
|
1226
|
+
lineIndex = chunk.intro.lastIndexOf(n);
|
|
1227
|
+
if (lineIndex !== -1) return chunk.intro.substr(lineIndex + 1) + lineStr;
|
|
1228
|
+
lineStr = chunk.intro + lineStr;
|
|
1229
|
+
}
|
|
1230
|
+
chunk = chunk.previous;
|
|
1231
|
+
}
|
|
1232
|
+
lineIndex = this.intro.lastIndexOf(n);
|
|
1233
|
+
if (lineIndex !== -1) return this.intro.substr(lineIndex + 1) + lineStr;
|
|
1234
|
+
return this.intro + lineStr;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Returns the content of the generated string that corresponds to the slice between `start` and `end` of the original string.
|
|
1238
|
+
* Throws error if the indices are for characters that were already removed.
|
|
1239
|
+
*/
|
|
1240
|
+
slice(start = 0, end = this.original.length - this.offset) {
|
|
1241
|
+
start = start + this.offset;
|
|
1242
|
+
end = end + this.offset;
|
|
1243
|
+
if (this.original.length !== 0) {
|
|
1244
|
+
if (start < 0) start = Math.max(0, start + this.original.length);
|
|
1245
|
+
if (end < 0) end = Math.max(0, end + this.original.length);
|
|
1246
|
+
}
|
|
1247
|
+
let result = "";
|
|
1248
|
+
let chunk = this.firstChunk;
|
|
1249
|
+
while (chunk && (chunk.start > start || chunk.end <= start)) {
|
|
1250
|
+
if (chunk.start < end && chunk.end >= end || end === 0 && chunk.start === 0) return result;
|
|
1251
|
+
chunk = chunk.next;
|
|
1252
|
+
}
|
|
1253
|
+
if (chunk && chunk.edited && chunk.start !== start) throw new MagicStringError(`cannot use edited character ${start} as slice start anchor`);
|
|
1254
|
+
const startChunk = chunk;
|
|
1255
|
+
while (chunk) {
|
|
1256
|
+
if (end === 0 && chunk.start === 0) break;
|
|
1257
|
+
if (chunk.intro && (startChunk !== chunk || chunk.start === start)) result += chunk.intro;
|
|
1258
|
+
const containsEnd = chunk.start < end && chunk.end >= end;
|
|
1259
|
+
if (containsEnd && chunk.edited && chunk.end !== end) throw new MagicStringError(`cannot use edited character ${end} as slice end anchor`);
|
|
1260
|
+
const sliceStart = startChunk === chunk ? start - chunk.start : 0;
|
|
1261
|
+
const sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
|
|
1262
|
+
result += chunk.content.slice(sliceStart, sliceEnd);
|
|
1263
|
+
if (chunk.outro && (!containsEnd || chunk.end === end)) result += chunk.outro;
|
|
1264
|
+
if (containsEnd) break;
|
|
1265
|
+
chunk = chunk.next;
|
|
1266
|
+
}
|
|
1267
|
+
return result;
|
|
1268
|
+
}
|
|
1269
|
+
/**
|
|
1270
|
+
* Returns a clone of `s`, with all content before the `start` and `end` characters of the original string removed.
|
|
1271
|
+
*/
|
|
1272
|
+
snip(start, end) {
|
|
1273
|
+
const clone = this.clone();
|
|
1274
|
+
clone.remove(0, start);
|
|
1275
|
+
clone.remove(end, clone.original.length);
|
|
1276
|
+
return clone;
|
|
1277
|
+
}
|
|
1278
|
+
/** @internal */
|
|
1279
|
+
_split(index) {
|
|
1280
|
+
if (this.byStart.get(index) || this.byEnd.get(index)) return;
|
|
1281
|
+
let chunk = this.lastSearchedChunk;
|
|
1282
|
+
let previousChunk = chunk;
|
|
1283
|
+
const searchForward = index > chunk.end;
|
|
1284
|
+
while (chunk) {
|
|
1285
|
+
if (chunk.contains(index)) return this._splitChunk(chunk, index);
|
|
1286
|
+
chunk = searchForward ? this.byStart.get(chunk.end) : this.byEnd.get(chunk.start);
|
|
1287
|
+
if (chunk === previousChunk) return;
|
|
1288
|
+
previousChunk = chunk;
|
|
1289
|
+
}
|
|
1290
|
+
}
|
|
1291
|
+
/** @internal */
|
|
1292
|
+
_splitChunk(chunk, index) {
|
|
1293
|
+
if (chunk.edited && chunk.content.length) {
|
|
1294
|
+
const loc = getLocator(this.original)(index);
|
|
1295
|
+
throw new MagicStringError(`cannot split a chunk that has already been edited (${loc.line}:${loc.column} – "${chunk.original}")`);
|
|
1296
|
+
}
|
|
1297
|
+
const newChunk = chunk.split(index);
|
|
1298
|
+
this.byEnd.set(index, chunk);
|
|
1299
|
+
this.byStart.set(index, newChunk);
|
|
1300
|
+
this.byEnd.set(newChunk.end, newChunk);
|
|
1301
|
+
if (chunk === this.lastChunk) this.lastChunk = newChunk;
|
|
1302
|
+
this.lastSearchedChunk = chunk;
|
|
1303
|
+
return true;
|
|
1304
|
+
}
|
|
1305
|
+
/**
|
|
1306
|
+
* Returns the generated string.
|
|
1307
|
+
*/
|
|
1308
|
+
toString() {
|
|
1309
|
+
let str = this.intro;
|
|
1310
|
+
let chunk = this.firstChunk;
|
|
1311
|
+
while (chunk) {
|
|
1312
|
+
str += chunk.toString();
|
|
1313
|
+
chunk = chunk.next;
|
|
1314
|
+
}
|
|
1315
|
+
return str + this.outro;
|
|
1316
|
+
}
|
|
1317
|
+
/**
|
|
1318
|
+
* Returns true if the resulting source is empty (disregarding white space).
|
|
1319
|
+
*/
|
|
1320
|
+
isEmpty() {
|
|
1321
|
+
if (this.intro.length && this.intro.trim()) return false;
|
|
1322
|
+
let chunk = this.firstChunk;
|
|
1323
|
+
while (chunk) {
|
|
1324
|
+
if (chunk.intro.length && chunk.intro.trim() || chunk.content.length && chunk.content.trim() || chunk.outro.length && chunk.outro.trim()) return false;
|
|
1325
|
+
chunk = chunk.next;
|
|
1326
|
+
}
|
|
1327
|
+
if (this.outro.length && this.outro.trim()) return false;
|
|
1328
|
+
return true;
|
|
1329
|
+
}
|
|
1330
|
+
length() {
|
|
1331
|
+
let chunk = this.firstChunk;
|
|
1332
|
+
let length = 0;
|
|
1333
|
+
while (chunk) {
|
|
1334
|
+
length += chunk.intro.length + chunk.content.length + chunk.outro.length;
|
|
1335
|
+
chunk = chunk.next;
|
|
1336
|
+
}
|
|
1337
|
+
return length;
|
|
1338
|
+
}
|
|
1339
|
+
/**
|
|
1340
|
+
* Removes empty lines from the start and end.
|
|
1341
|
+
*/
|
|
1342
|
+
trimLines() {
|
|
1343
|
+
return this.trim("[\\r\\n]");
|
|
1344
|
+
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start and end.
|
|
1347
|
+
*/
|
|
1348
|
+
trim(charType) {
|
|
1349
|
+
return this.trimStart(charType).trimEnd(charType);
|
|
1350
|
+
}
|
|
1351
|
+
/** @internal */
|
|
1352
|
+
trimEndAborted(charType) {
|
|
1353
|
+
const rx = new RegExp(`${charType || "\\s"}+$`);
|
|
1354
|
+
this.outro = this.outro.replace(rx, "");
|
|
1355
|
+
if (this.outro.length) return true;
|
|
1356
|
+
let chunk = this.lastChunk;
|
|
1357
|
+
do {
|
|
1358
|
+
const end = chunk.end;
|
|
1359
|
+
const aborted = chunk.trimEnd(rx);
|
|
1360
|
+
if (chunk.end !== end) {
|
|
1361
|
+
if (this.lastChunk === chunk) this.lastChunk = chunk.next;
|
|
1362
|
+
this.byEnd.set(chunk.end, chunk);
|
|
1363
|
+
this.byStart.set(chunk.next.start, chunk.next);
|
|
1364
|
+
this.byEnd.set(chunk.next.end, chunk.next);
|
|
1365
|
+
}
|
|
1366
|
+
if (aborted) return true;
|
|
1367
|
+
chunk = chunk.previous;
|
|
1368
|
+
} while (chunk);
|
|
1369
|
+
this.intro = this.intro.replace(rx, "");
|
|
1370
|
+
return this.intro.length > 0;
|
|
1371
|
+
}
|
|
1372
|
+
/**
|
|
1373
|
+
* Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the end.
|
|
1374
|
+
*/
|
|
1375
|
+
trimEnd(charType) {
|
|
1376
|
+
this.trimEndAborted(charType);
|
|
1377
|
+
return this;
|
|
1378
|
+
}
|
|
1379
|
+
/** @internal */
|
|
1380
|
+
trimStartAborted(charType) {
|
|
1381
|
+
const rx = new RegExp(`^${charType || "\\s"}+`);
|
|
1382
|
+
this.intro = this.intro.replace(rx, "");
|
|
1383
|
+
if (this.intro.length) return true;
|
|
1384
|
+
let chunk = this.firstChunk;
|
|
1385
|
+
do {
|
|
1386
|
+
const end = chunk.end;
|
|
1387
|
+
const aborted = chunk.trimStart(rx);
|
|
1388
|
+
if (chunk.end !== end) {
|
|
1389
|
+
if (chunk === this.lastChunk) this.lastChunk = chunk.next;
|
|
1390
|
+
this.byEnd.set(chunk.end, chunk);
|
|
1391
|
+
this.byStart.set(chunk.next.start, chunk.next);
|
|
1392
|
+
this.byEnd.set(chunk.next.end, chunk.next);
|
|
1393
|
+
}
|
|
1394
|
+
if (aborted) return true;
|
|
1395
|
+
chunk = chunk.next;
|
|
1396
|
+
} while (chunk);
|
|
1397
|
+
this.outro = this.outro.replace(rx, "");
|
|
1398
|
+
return this.outro.length > 0;
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Trims content matching `charType` (defaults to `\s`, i.e. whitespace) from the start.
|
|
1402
|
+
*/
|
|
1403
|
+
trimStart(charType) {
|
|
1404
|
+
this.trimStartAborted(charType);
|
|
1405
|
+
return this;
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Indicates if the string has been changed.
|
|
1409
|
+
*/
|
|
1410
|
+
hasChanged() {
|
|
1411
|
+
if (this.intro || this.outro) return true;
|
|
1412
|
+
let outputIndex = 0;
|
|
1413
|
+
let chunk = this.firstChunk;
|
|
1414
|
+
while (chunk) {
|
|
1415
|
+
if (chunk.intro || chunk.outro) return true;
|
|
1416
|
+
if (!chunk.edited && chunk.start === outputIndex) outputIndex = chunk.end;
|
|
1417
|
+
else {
|
|
1418
|
+
if (!this.original.startsWith(chunk.content, outputIndex)) return true;
|
|
1419
|
+
outputIndex += chunk.content.length;
|
|
1420
|
+
}
|
|
1421
|
+
chunk = chunk.next;
|
|
1422
|
+
}
|
|
1423
|
+
return outputIndex !== this.original.length;
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Whether the original range [start, end) has had any of its characters
|
|
1427
|
+
* removed. `replace`/`replaceAll` search `original`, so a match can land on
|
|
1428
|
+
* text that is no longer in the output - overwriting it would resurrect the
|
|
1429
|
+
* removed characters, so such matches are skipped instead.
|
|
1430
|
+
*
|
|
1431
|
+
* @internal
|
|
1432
|
+
*/
|
|
1433
|
+
_hasRemovedContent(start, end) {
|
|
1434
|
+
let chunk = this.firstChunk;
|
|
1435
|
+
while (chunk) {
|
|
1436
|
+
if (chunk.content === "" && chunk.start < end && chunk.end > start) return true;
|
|
1437
|
+
chunk = chunk.next;
|
|
1438
|
+
}
|
|
1439
|
+
return false;
|
|
1440
|
+
}
|
|
1441
|
+
/** @internal */
|
|
1442
|
+
_replaceRegexp(searchValue, replacement) {
|
|
1443
|
+
function getReplacement(match, str) {
|
|
1444
|
+
if (typeof replacement === "string") return expandReplacement(replacement, match[0], match.index, str, match.slice(1), match.groups);
|
|
1445
|
+
else return match.groups === void 0 ? replacement(match[0], ...match.slice(1), match.index, str) : replacement(match[0], ...match.slice(1), match.index, str, match.groups);
|
|
1446
|
+
}
|
|
1447
|
+
const replaceMatch = (match) => {
|
|
1448
|
+
/* v8 ignore next 2 -- `match.index` is always defined for matches from `matchAll` */
|
|
1449
|
+
if (match.index == null) return false;
|
|
1450
|
+
if (this._hasRemovedContent(match.index, match.index + match[0].length)) return false;
|
|
1451
|
+
const replacement = getReplacement(match, this.original);
|
|
1452
|
+
if (replacement === match[0]) return true;
|
|
1453
|
+
if (match[0].length === 0) this.appendRight(match.index, replacement);
|
|
1454
|
+
else this.overwrite(match.index, match.index + match[0].length, replacement);
|
|
1455
|
+
return true;
|
|
1456
|
+
};
|
|
1457
|
+
if (searchValue.global) {
|
|
1458
|
+
searchValue.lastIndex = 0;
|
|
1459
|
+
for (const match of this.original.matchAll(searchValue)) replaceMatch(match);
|
|
1460
|
+
} else {
|
|
1461
|
+
const match = this.original.match(searchValue);
|
|
1462
|
+
if (match && !replaceMatch(match)) {
|
|
1463
|
+
const global = new RegExp(searchValue.source, `${searchValue.flags}g`);
|
|
1464
|
+
for (const next of this.original.matchAll(global)) if (replaceMatch(next)) break;
|
|
1465
|
+
}
|
|
1466
|
+
}
|
|
1467
|
+
return this;
|
|
1468
|
+
}
|
|
1469
|
+
/** @internal */
|
|
1470
|
+
_replaceString(string, replacement) {
|
|
1471
|
+
const { original } = this;
|
|
1472
|
+
let index = original.indexOf(string);
|
|
1473
|
+
while (index !== -1) {
|
|
1474
|
+
if (this._hasRemovedContent(index, index + string.length)) {
|
|
1475
|
+
index = original.indexOf(string, index + string.length);
|
|
1476
|
+
continue;
|
|
1477
|
+
}
|
|
1478
|
+
if (typeof replacement === "function") replacement = replacement(string, index, original);
|
|
1479
|
+
else replacement = expandReplacement(replacement, string, index, original, [], void 0);
|
|
1480
|
+
if (string !== replacement) {
|
|
1481
|
+
if (string.length === 0) this.appendRight(index, replacement);
|
|
1482
|
+
else this.overwrite(index, index + string.length, replacement);
|
|
1483
|
+
}
|
|
1484
|
+
break;
|
|
1485
|
+
}
|
|
1486
|
+
return this;
|
|
1487
|
+
}
|
|
1488
|
+
/**
|
|
1489
|
+
* String replacement with RegExp or string.
|
|
1490
|
+
*/
|
|
1491
|
+
replace(searchValue, replacement) {
|
|
1492
|
+
if (typeof searchValue === "string") return this._replaceString(searchValue, replacement);
|
|
1493
|
+
return this._replaceRegexp(searchValue, replacement);
|
|
1494
|
+
}
|
|
1495
|
+
/** @internal */
|
|
1496
|
+
_replaceAllString(string, replacement) {
|
|
1497
|
+
const { original } = this;
|
|
1498
|
+
const stringLength = string.length;
|
|
1499
|
+
if (stringLength === 0) {
|
|
1500
|
+
for (let index = 0; index <= original.length; index += 1) {
|
|
1501
|
+
const _replacement = typeof replacement === "function" ? replacement("", index, original) : expandReplacement(replacement, "", index, original, [], void 0);
|
|
1502
|
+
if (_replacement !== "") this.appendRight(index, _replacement);
|
|
1503
|
+
}
|
|
1504
|
+
return this;
|
|
1505
|
+
}
|
|
1506
|
+
for (let index = original.indexOf(string); index !== -1; index = original.indexOf(string, index + stringLength)) {
|
|
1507
|
+
if (this._hasRemovedContent(index, index + stringLength)) continue;
|
|
1508
|
+
const previous = original.slice(index, index + stringLength);
|
|
1509
|
+
const _replacement = typeof replacement === "function" ? replacement(previous, index, original) : expandReplacement(replacement, previous, index, original, [], void 0);
|
|
1510
|
+
if (previous !== _replacement) this.overwrite(index, index + stringLength, _replacement);
|
|
1511
|
+
}
|
|
1512
|
+
return this;
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Same as `s.replace`, but replace all matched strings instead of just one.
|
|
1516
|
+
*/
|
|
1517
|
+
replaceAll(searchValue, replacement) {
|
|
1518
|
+
if (typeof searchValue === "string") return this._replaceAllString(searchValue, replacement);
|
|
1519
|
+
if (!searchValue.global) throw new MagicStringError("replaceAll() requires a global RegExp");
|
|
1520
|
+
return this._replaceRegexp(searchValue, replacement);
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1523
|
+
//#endregion
|
|
1524
|
+
export { MagicString, MagicString as default };
|