dismantle 0.2.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.
Files changed (73) hide show
  1. package/LICENSE +7 -0
  2. package/README.md +40 -0
  3. package/dist/cjs/development/index.cjs +1484 -0
  4. package/dist/cjs/development/index.cjs.map +7 -0
  5. package/dist/cjs/development/runtime.cjs +1484 -0
  6. package/dist/cjs/development/runtime.cjs.map +7 -0
  7. package/dist/cjs/production/index.cjs +1 -0
  8. package/dist/cjs/production/runtime.cjs +1 -0
  9. package/dist/esm/development/index.mjs +1453 -0
  10. package/dist/esm/development/index.mjs.map +7 -0
  11. package/dist/esm/development/runtime.mjs +1453 -0
  12. package/dist/esm/development/runtime.mjs.map +7 -0
  13. package/dist/esm/production/index.mjs +1 -0
  14. package/dist/esm/production/runtime.mjs +1 -0
  15. package/dist/types/hidden-imports.d.ts +4 -0
  16. package/dist/types/hidden-imports.d.ts.map +1 -0
  17. package/dist/types/index.d.ts +9 -0
  18. package/dist/types/index.d.ts.map +1 -0
  19. package/dist/types/plugin.d.ts +8 -0
  20. package/dist/types/plugin.d.ts.map +1 -0
  21. package/dist/types/split.d.ts +7 -0
  22. package/dist/types/split.d.ts.map +1 -0
  23. package/dist/types/transform-block.d.ts +5 -0
  24. package/dist/types/transform-block.d.ts.map +1 -0
  25. package/dist/types/transform-call.d.ts +5 -0
  26. package/dist/types/transform-call.d.ts.map +1 -0
  27. package/dist/types/types.d.ts +62 -0
  28. package/dist/types/types.d.ts.map +1 -0
  29. package/dist/types/utils/assert.d.ts +2 -0
  30. package/dist/types/utils/assert.d.ts.map +1 -0
  31. package/dist/types/utils/generator-shim.d.ts +4 -0
  32. package/dist/types/utils/generator-shim.d.ts.map +1 -0
  33. package/dist/types/utils/get-descriptive-name.d.ts +3 -0
  34. package/dist/types/utils/get-descriptive-name.d.ts.map +1 -0
  35. package/dist/types/utils/get-foreign-bindings.d.ts +3 -0
  36. package/dist/types/utils/get-foreign-bindings.d.ts.map +1 -0
  37. package/dist/types/utils/get-identifiers-from-lval.d.ts +3 -0
  38. package/dist/types/utils/get-identifiers-from-lval.d.ts.map +1 -0
  39. package/dist/types/utils/get-import-identifier.d.ts +5 -0
  40. package/dist/types/utils/get-import-identifier.d.ts.map +1 -0
  41. package/dist/types/utils/get-import-specifier-name.d.ts +3 -0
  42. package/dist/types/utils/get-import-specifier-name.d.ts.map +1 -0
  43. package/dist/types/utils/get-module-definition.d.ts +4 -0
  44. package/dist/types/utils/get-module-definition.d.ts.map +1 -0
  45. package/dist/types/utils/get-root-statement-path.d.ts +3 -0
  46. package/dist/types/utils/get-root-statement-path.d.ts.map +1 -0
  47. package/dist/types/utils/register-import-specifiers.d.ts +5 -0
  48. package/dist/types/utils/register-import-specifiers.d.ts.map +1 -0
  49. package/dist/types/utils/unwrap.d.ts +11 -0
  50. package/dist/types/utils/unwrap.d.ts.map +1 -0
  51. package/dist/types/utils/xxhash32.d.ts +7 -0
  52. package/dist/types/utils/xxhash32.d.ts.map +1 -0
  53. package/package.json +90 -0
  54. package/src/hidden-imports.ts +13 -0
  55. package/src/index.ts +90 -0
  56. package/src/plugin.ts +26 -0
  57. package/src/split.ts +1074 -0
  58. package/src/transform-block.ts +115 -0
  59. package/src/transform-call.ts +100 -0
  60. package/src/types.ts +73 -0
  61. package/src/utils/assert.ts +5 -0
  62. package/src/utils/errors.ts +21 -0
  63. package/src/utils/generator-shim.ts +22 -0
  64. package/src/utils/get-descriptive-name.ts +42 -0
  65. package/src/utils/get-foreign-bindings.ts +60 -0
  66. package/src/utils/get-identifiers-from-lval.ts +44 -0
  67. package/src/utils/get-import-identifier.ts +23 -0
  68. package/src/utils/get-import-specifier-name.ts +10 -0
  69. package/src/utils/get-module-definition.ts +53 -0
  70. package/src/utils/get-root-statement-path.ts +14 -0
  71. package/src/utils/register-import-specifiers.ts +77 -0
  72. package/src/utils/unwrap.ts +63 -0
  73. package/src/utils/xxhash32.ts +214 -0
@@ -0,0 +1,1453 @@
1
+ // src/index.ts
2
+ import * as babel from "@babel/core";
3
+ import path from "node:path";
4
+
5
+ // src/split.ts
6
+ import * as t5 from "@babel/types";
7
+
8
+ // src/hidden-imports.ts
9
+ var HIDDEN_FUNC = {
10
+ kind: "named",
11
+ source: "dismantle/runtime",
12
+ name: "$$func"
13
+ };
14
+ var HIDDEN_GENERATOR = {
15
+ kind: "named",
16
+ source: "dismantle/runtime",
17
+ name: "$$gen"
18
+ };
19
+
20
+ // src/utils/assert.ts
21
+ function assert(cond, error) {
22
+ if (!cond) {
23
+ throw new Error(error);
24
+ }
25
+ }
26
+
27
+ // src/utils/generator-shim.ts
28
+ import _generator from "@babel/generator";
29
+ var generator = typeof _generator !== "function" ? _generator.default : _generator;
30
+ function generateCode(id, node) {
31
+ const result = generator(node, {
32
+ sourceMaps: true,
33
+ sourceFileName: id
34
+ });
35
+ return {
36
+ code: result.code,
37
+ map: result.map
38
+ };
39
+ }
40
+
41
+ // src/utils/get-descriptive-name.ts
42
+ function getDescriptiveName(path2, defaultName) {
43
+ let current = path2;
44
+ while (current) {
45
+ switch (current.node.type) {
46
+ case "FunctionDeclaration":
47
+ case "FunctionExpression": {
48
+ if (current.node.id) {
49
+ return current.node.id.name;
50
+ }
51
+ break;
52
+ }
53
+ case "VariableDeclarator": {
54
+ if (current.node.id.type === "Identifier") {
55
+ return current.node.id.name;
56
+ }
57
+ break;
58
+ }
59
+ case "ClassPrivateMethod":
60
+ case "ClassMethod":
61
+ case "ObjectMethod": {
62
+ switch (current.node.key.type) {
63
+ case "Identifier":
64
+ return current.node.key.name;
65
+ case "PrivateName":
66
+ return current.node.key.id.name;
67
+ default:
68
+ break;
69
+ }
70
+ break;
71
+ }
72
+ default:
73
+ break;
74
+ }
75
+ current = current.parentPath;
76
+ }
77
+ return defaultName;
78
+ }
79
+
80
+ // src/utils/get-foreign-bindings.ts
81
+ import * as t from "@babel/types";
82
+ function isForeignBinding(source, current, name, mode) {
83
+ if (current.scope.hasGlobal(name)) {
84
+ return false;
85
+ }
86
+ if (source === current) {
87
+ return true;
88
+ }
89
+ if (current.scope.hasOwnBinding(name)) {
90
+ if (mode === "block") {
91
+ const binding = current.scope.getBinding(name);
92
+ return !!binding && binding.kind === "param";
93
+ }
94
+ return false;
95
+ }
96
+ if (current.parentPath) {
97
+ return isForeignBinding(source, current.parentPath, name, mode);
98
+ }
99
+ return true;
100
+ }
101
+ function isInTypescript(path2) {
102
+ let parent = path2.parentPath;
103
+ while (parent) {
104
+ if (t.isTypeScript(parent.node) && !t.isExpression(parent.node)) {
105
+ return true;
106
+ }
107
+ parent = parent.parentPath;
108
+ }
109
+ return false;
110
+ }
111
+ function getForeignBindings(path2, mode) {
112
+ const identifiers = /* @__PURE__ */ new Set();
113
+ path2.traverse({
114
+ ReferencedIdentifier(p) {
115
+ if (!isInTypescript(p) && (mode === "expression" ? !path2.scope.hasGlobal(p.node.name) : isForeignBinding(path2, p, p.node.name, mode))) {
116
+ identifiers.add(p.node.name);
117
+ }
118
+ }
119
+ });
120
+ return identifiers;
121
+ }
122
+
123
+ // src/utils/get-identifiers-from-lval.ts
124
+ import * as t2 from "@babel/types";
125
+ function getIdentifiersFromArrayPattern(node) {
126
+ const ids = [];
127
+ for (let i = 0, len = node.elements.length; i < len; i++) {
128
+ const el = node.elements[i];
129
+ if (el) {
130
+ ids.push(...getIdentifiersFromLVal(el));
131
+ }
132
+ }
133
+ return ids;
134
+ }
135
+ function getIdentifiersFromObjectPattern(node) {
136
+ const ids = [];
137
+ for (let i = 0, len = node.properties.length; i < len; i++) {
138
+ const el = node.properties[i];
139
+ if (el) {
140
+ if (el.type === "RestElement") {
141
+ ids.push(...getIdentifiersFromLVal(el));
142
+ } else if (t2.isLVal(el.value)) {
143
+ ids.push(...getIdentifiersFromLVal(el.value));
144
+ }
145
+ }
146
+ }
147
+ return ids;
148
+ }
149
+ function getIdentifiersFromLVal(node) {
150
+ switch (node.type) {
151
+ case "Identifier":
152
+ return [node.name];
153
+ case "ArrayPattern":
154
+ return getIdentifiersFromArrayPattern(node);
155
+ case "AssignmentPattern":
156
+ return getIdentifiersFromLVal(node.left);
157
+ case "ObjectPattern":
158
+ return getIdentifiersFromObjectPattern(node);
159
+ case "RestElement":
160
+ return getIdentifiersFromLVal(node.argument);
161
+ default:
162
+ return [];
163
+ }
164
+ }
165
+
166
+ // src/utils/get-import-identifier.ts
167
+ import { addDefault, addNamed } from "@babel/helper-module-imports";
168
+ function getImportIdentifier(state, path2, registration) {
169
+ const name = registration.kind === "named" ? registration.name : "default";
170
+ const target = `${registration.source}[${name}]`;
171
+ const current = state.imports.get(target);
172
+ if (current) {
173
+ return current;
174
+ }
175
+ const newID = registration.kind === "named" ? addNamed(path2, registration.name, registration.source) : addDefault(path2, registration.source);
176
+ state.imports.set(target, newID);
177
+ return newID;
178
+ }
179
+
180
+ // src/utils/get-module-definition.ts
181
+ import * as t3 from "@babel/types";
182
+
183
+ // src/utils/get-import-specifier-name.ts
184
+ function getImportSpecifierName(node) {
185
+ switch (node.imported.type) {
186
+ case "Identifier":
187
+ return node.imported.name;
188
+ case "StringLiteral":
189
+ return node.imported.value;
190
+ }
191
+ }
192
+
193
+ // src/utils/unwrap.ts
194
+ function isPathValid(path2, key) {
195
+ return key(path2.node);
196
+ }
197
+ function isNestedExpression(node) {
198
+ switch (node.type) {
199
+ case "ParenthesizedExpression":
200
+ case "TypeCastExpression":
201
+ case "TSAsExpression":
202
+ case "TSSatisfiesExpression":
203
+ case "TSNonNullExpression":
204
+ case "TSTypeAssertion":
205
+ case "TSInstantiationExpression":
206
+ return true;
207
+ default:
208
+ return false;
209
+ }
210
+ }
211
+ function unwrapNode(node, key) {
212
+ if (key(node)) {
213
+ return node;
214
+ }
215
+ if (isNestedExpression(node)) {
216
+ return unwrapNode(node.expression, key);
217
+ }
218
+ return void 0;
219
+ }
220
+ function unwrapPath(path2, key) {
221
+ if (isPathValid(path2, key)) {
222
+ return path2;
223
+ }
224
+ if (isPathValid(path2, isNestedExpression)) {
225
+ return unwrapPath(path2.get("expression"), key);
226
+ }
227
+ return void 0;
228
+ }
229
+
230
+ // src/utils/get-module-definition.ts
231
+ function getModuleDefinition(path2) {
232
+ if (!(isPathValid(path2, t3.isImportSpecifier) || isPathValid(path2, t3.isImportDefaultSpecifier) || isPathValid(path2, t3.isImportNamespaceSpecifier))) {
233
+ return void 0;
234
+ }
235
+ const parent = path2.getStatementParent();
236
+ const source = parent.node.source.value;
237
+ switch (path2.node.type) {
238
+ case "ImportDefaultSpecifier":
239
+ return {
240
+ source,
241
+ kind: "default",
242
+ local: path2.node.local.name
243
+ };
244
+ case "ImportNamespaceSpecifier":
245
+ return {
246
+ source,
247
+ kind: "namespace",
248
+ local: path2.node.local.name
249
+ };
250
+ case "ImportSpecifier": {
251
+ const imported = getImportSpecifierName(path2.node);
252
+ if (imported === "default") {
253
+ return {
254
+ source,
255
+ kind: "default",
256
+ local: path2.node.local.name,
257
+ imported: ""
258
+ };
259
+ }
260
+ return {
261
+ source,
262
+ kind: "named",
263
+ local: path2.node.local.name,
264
+ imported
265
+ };
266
+ }
267
+ }
268
+ }
269
+
270
+ // src/utils/get-root-statement-path.ts
271
+ import * as t4 from "@babel/types";
272
+ function getRootStatementPath(path2) {
273
+ let current = path2.parentPath;
274
+ while (current) {
275
+ const next = current.parentPath;
276
+ if (next && t4.isProgram(next.node)) {
277
+ return current;
278
+ }
279
+ current = next;
280
+ }
281
+ return path2;
282
+ }
283
+
284
+ // src/split.ts
285
+ function moduleDefinitionToImportSpecifier(definition) {
286
+ switch (definition.kind) {
287
+ case "default":
288
+ return t5.importDefaultSpecifier(t5.identifier(definition.local));
289
+ case "named":
290
+ return t5.importSpecifier(
291
+ t5.identifier(definition.local),
292
+ definition.imported ? t5.identifier(definition.imported) : t5.identifier(definition.local)
293
+ );
294
+ case "namespace":
295
+ return t5.importNamespaceSpecifier(t5.identifier(definition.local));
296
+ }
297
+ }
298
+ function moduleDefinitionToImportDeclaration(definition) {
299
+ return t5.importDeclaration(
300
+ [moduleDefinitionToImportSpecifier(definition)],
301
+ t5.stringLiteral(definition.source)
302
+ );
303
+ }
304
+ function moduleDefinitionsToImportDeclarations(definitions) {
305
+ const declarations = [];
306
+ for (let i = 0, len = definitions.length; i < len; i++) {
307
+ declarations[i] = moduleDefinitionToImportDeclaration(definitions[i]);
308
+ }
309
+ return declarations;
310
+ }
311
+ function isMutation(kind) {
312
+ switch (kind) {
313
+ case "let":
314
+ case "var":
315
+ case "param":
316
+ return true;
317
+ case "const":
318
+ case "hoisted":
319
+ case "local":
320
+ case "module":
321
+ case "unknown":
322
+ return false;
323
+ }
324
+ }
325
+ function registerModuleLevelBinding(ctx, modules, binding, target) {
326
+ const current = ctx.bindings.get(binding);
327
+ if (current) {
328
+ modules.push(current);
329
+ } else if (isPathValid(target.path, t5.isVariableDeclarator)) {
330
+ const definitions = splitVariableDeclarator(ctx, target.path);
331
+ for (let k = 0, klen = definitions.length; k < klen; k++) {
332
+ modules.push(definitions[k]);
333
+ ctx.bindings.set(definitions[k].local, definitions[k]);
334
+ }
335
+ } else if (isPathValid(target.path, t5.isFunctionDeclaration)) {
336
+ const definition = splitFunctionDeclaration(ctx, target.path);
337
+ modules.push(definition);
338
+ ctx.bindings.set(definition.local, definition);
339
+ }
340
+ }
341
+ function registerBinding(ctx, modules, locals, mutations, binding, target, pure) {
342
+ if (target.kind === "module") {
343
+ const result = getModuleDefinition(target.path);
344
+ if (result) {
345
+ modules.push(result);
346
+ }
347
+ } else if (target.kind === "param") {
348
+ locals.push(target.identifier);
349
+ } else {
350
+ let blockParent = target.path.scope.getBlockParent();
351
+ const programParent = target.path.scope.getProgramParent();
352
+ if (blockParent.path === target.path) {
353
+ blockParent = blockParent.parent;
354
+ }
355
+ if (blockParent === programParent) {
356
+ registerModuleLevelBinding(ctx, modules, binding, target);
357
+ } else if (!pure) {
358
+ locals.push(target.identifier);
359
+ if (isMutation(target.kind)) {
360
+ mutations.push(target.identifier);
361
+ }
362
+ }
363
+ }
364
+ }
365
+ function extractBindings(ctx, path2, bindings, pure) {
366
+ const modules = [];
367
+ const locals = [];
368
+ const mutations = [];
369
+ for (const binding of bindings) {
370
+ const target = path2.scope.getBinding(binding);
371
+ if (target) {
372
+ registerBinding(ctx, modules, locals, mutations, binding, target, pure);
373
+ }
374
+ }
375
+ return {
376
+ modules,
377
+ locals,
378
+ mutations
379
+ };
380
+ }
381
+ function createVirtualFileName(ctx) {
382
+ return `./${ctx.path.base}?${ctx.options.key}=${ctx.virtual.count++}${ctx.path.ext}`;
383
+ }
384
+ function createRootFile(ctx, bindings, replacement) {
385
+ const rootFile = createVirtualFileName(ctx);
386
+ const rootContent = generateCode(
387
+ ctx.id,
388
+ t5.program([
389
+ ...ctx.options.mode === "server" ? moduleDefinitionsToImportDeclarations(bindings.modules) : [],
390
+ t5.exportDefaultDeclaration(replacement)
391
+ ])
392
+ );
393
+ ctx.onVirtualFile(
394
+ rootFile,
395
+ { code: rootContent.code, map: rootContent.map },
396
+ "root"
397
+ );
398
+ return rootFile;
399
+ }
400
+ function createEntryFile(ctx, path2, rootFile, imported) {
401
+ let id = `${ctx.blocks.hash}-${ctx.blocks.count++}`;
402
+ if (ctx.options.env !== "production") {
403
+ id += `-${getDescriptiveName(path2, "anonymous")}`;
404
+ }
405
+ const entryID = path2.scope.generateUidIdentifier("entry");
406
+ const entryImports = [
407
+ {
408
+ kind: imported.kind,
409
+ source: imported.source,
410
+ local: entryID.name,
411
+ imported: imported.kind === "named" ? imported.name : void 0
412
+ }
413
+ ];
414
+ const args = [t5.stringLiteral(id)];
415
+ if (ctx.options.mode === "server") {
416
+ const rootID = path2.scope.generateUidIdentifier("root");
417
+ entryImports.push({
418
+ kind: "default",
419
+ source: rootFile,
420
+ local: rootID.name
421
+ });
422
+ args.push(rootID);
423
+ }
424
+ const entryFile = createVirtualFileName(ctx);
425
+ const entryContent = generateCode(
426
+ ctx.id,
427
+ t5.program([
428
+ ...moduleDefinitionsToImportDeclarations(entryImports),
429
+ t5.exportDefaultDeclaration(t5.callExpression(entryID, args))
430
+ ])
431
+ );
432
+ ctx.onVirtualFile(
433
+ entryFile,
434
+ { code: entryContent.code, map: entryContent.map },
435
+ "entry"
436
+ );
437
+ return entryFile;
438
+ }
439
+ function splitFunctionDeclaration(ctx, path2) {
440
+ const bindings = getForeignBindings(path2, "function");
441
+ const { modules } = extractBindings(ctx, path2, bindings);
442
+ const file = createVirtualFileName(ctx);
443
+ const compiled = generateCode(
444
+ ctx.id,
445
+ t5.program([
446
+ ...moduleDefinitionsToImportDeclarations(modules),
447
+ t5.exportNamedDeclaration(path2.node)
448
+ ])
449
+ );
450
+ ctx.onVirtualFile(file, { code: compiled.code, map: compiled.map }, "none");
451
+ const statement = getRootStatementPath(path2);
452
+ const identifier2 = path2.node.id || path2.scope.generateUidIdentifier("func");
453
+ const definition = {
454
+ kind: "named",
455
+ local: identifier2.name,
456
+ source: file
457
+ };
458
+ statement.insertBefore(moduleDefinitionToImportDeclaration(definition));
459
+ path2.remove();
460
+ return definition;
461
+ }
462
+ function splitVariableDeclarator(ctx, path2) {
463
+ const init = unwrapPath(path2.get("init"), t5.isExpression);
464
+ const modules = init ? extractBindings(
465
+ ctx,
466
+ path2,
467
+ getForeignBindings(
468
+ path2,
469
+ isPathValid(init, t5.isArrowFunctionExpression) || isPathValid(init, t5.isFunctionExpression) ? "function" : "expression"
470
+ )
471
+ ).modules : [];
472
+ const file = createVirtualFileName(ctx);
473
+ const parent = path2.parentPath.node;
474
+ const compiled = generateCode(
475
+ ctx.id,
476
+ t5.program([
477
+ ...moduleDefinitionsToImportDeclarations(modules),
478
+ t5.exportNamedDeclaration(t5.variableDeclaration(parent.kind, [path2.node]))
479
+ ])
480
+ );
481
+ ctx.onVirtualFile(file, { code: compiled.code, map: compiled.map }, "none");
482
+ const definitions = getIdentifiersFromLVal(
483
+ path2.node.id
484
+ ).map((name) => ({
485
+ kind: "named",
486
+ local: name,
487
+ source: file
488
+ }));
489
+ const statement = getRootStatementPath(path2);
490
+ if (statement) {
491
+ statement.insertBefore(moduleDefinitionsToImportDeclarations(definitions));
492
+ }
493
+ path2.remove();
494
+ return definitions;
495
+ }
496
+ var BREAK_KEY = t5.numericLiteral(0);
497
+ var CONTINUE_KEY = t5.numericLiteral(1);
498
+ var RETURN_KEY = t5.numericLiteral(2);
499
+ var NO_HALT_KEY = t5.numericLiteral(3);
500
+ var THROW_KEY = t5.numericLiteral(4);
501
+ var YIELD_KEY = t5.numericLiteral(5);
502
+ function transformBlockContent(path2, mutations) {
503
+ const target = path2.scope.getFunctionParent() || path2.scope.getProgramParent();
504
+ const breaks = [];
505
+ let breakCount = 0;
506
+ const continues = [];
507
+ let continueCount = 0;
508
+ let hasReturn = false;
509
+ let hasYield = false;
510
+ const applyMutations = mutations.length ? path2.scope.generateUidIdentifier("mutate") : void 0;
511
+ path2.traverse({
512
+ BreakStatement(child) {
513
+ const parent = child.scope.getFunctionParent() || child.scope.getProgramParent();
514
+ if (parent === target) {
515
+ const replacement = [BREAK_KEY];
516
+ breakCount++;
517
+ if (child.node.label) {
518
+ const targetName = child.node.label.name;
519
+ breaks.push(targetName);
520
+ replacement.push(t5.stringLiteral(targetName));
521
+ } else {
522
+ replacement.push(t5.nullLiteral());
523
+ }
524
+ if (applyMutations) {
525
+ replacement.push(t5.callExpression(applyMutations, []));
526
+ }
527
+ child.replaceWith(t5.returnStatement(t5.arrayExpression(replacement)));
528
+ child.skip();
529
+ }
530
+ },
531
+ ContinueStatement(child) {
532
+ const parent = child.scope.getFunctionParent() || child.scope.getProgramParent();
533
+ if (parent === target) {
534
+ const replacement = [CONTINUE_KEY];
535
+ continueCount++;
536
+ if (child.node.label) {
537
+ const targetName = child.node.label.name;
538
+ continues.push(targetName);
539
+ replacement.push(t5.stringLiteral(targetName));
540
+ } else {
541
+ replacement.push(t5.nullLiteral());
542
+ }
543
+ if (applyMutations) {
544
+ replacement.push(t5.callExpression(applyMutations, []));
545
+ }
546
+ child.replaceWith(t5.returnStatement(t5.arrayExpression(replacement)));
547
+ child.skip();
548
+ }
549
+ },
550
+ ReturnStatement(child) {
551
+ const parent = child.scope.getFunctionParent() || child.scope.getProgramParent();
552
+ if (parent === target) {
553
+ hasReturn = true;
554
+ const arg = child.get("argument");
555
+ arg.replaceWith(
556
+ t5.arrayExpression([
557
+ RETURN_KEY,
558
+ arg.node ? arg.node : t5.nullLiteral(),
559
+ applyMutations ? t5.callExpression(applyMutations, []) : t5.nullLiteral()
560
+ ])
561
+ );
562
+ }
563
+ },
564
+ YieldExpression(child) {
565
+ const parent = child.scope.getFunctionParent() || child.scope.getProgramParent();
566
+ if (parent === target) {
567
+ hasYield = true;
568
+ if (child.node.delegate) {
569
+ } else {
570
+ const arg = child.get("argument");
571
+ arg.replaceWith(
572
+ t5.arrayExpression([
573
+ YIELD_KEY,
574
+ arg.node ? arg.node : t5.nullLiteral(),
575
+ applyMutations ? t5.callExpression(applyMutations, []) : t5.nullLiteral()
576
+ ])
577
+ );
578
+ }
579
+ }
580
+ }
581
+ });
582
+ const error = path2.scope.generateUidIdentifier("error");
583
+ const throwResult = [THROW_KEY, error];
584
+ const haltResult = [NO_HALT_KEY];
585
+ if (applyMutations) {
586
+ throwResult.push(t5.callExpression(applyMutations, []));
587
+ haltResult.push(t5.nullLiteral());
588
+ haltResult.push(t5.callExpression(applyMutations, []));
589
+ }
590
+ const statements = [
591
+ t5.tryStatement(
592
+ t5.blockStatement(path2.node.body),
593
+ t5.catchClause(
594
+ error,
595
+ t5.blockStatement([t5.returnStatement(t5.arrayExpression(throwResult))])
596
+ )
597
+ ),
598
+ t5.returnStatement(t5.arrayExpression(haltResult))
599
+ ];
600
+ if (applyMutations) {
601
+ statements.unshift(
602
+ t5.variableDeclaration("const", [
603
+ t5.variableDeclarator(
604
+ applyMutations,
605
+ t5.arrowFunctionExpression(
606
+ [],
607
+ t5.objectExpression(
608
+ mutations.map((item) => t5.objectProperty(item, item, false, true))
609
+ )
610
+ )
611
+ )
612
+ ])
613
+ );
614
+ }
615
+ path2.node.body = statements;
616
+ return { breaks, continues, hasReturn, hasYield, breakCount, continueCount };
617
+ }
618
+ function getBreakCheck(returnType, returnResult, breakCount, breaks, check) {
619
+ let current;
620
+ if (breakCount !== breaks.length) {
621
+ current = t5.blockStatement([t5.breakStatement()]);
622
+ }
623
+ for (let i = 0, len = breaks.length; i < len; i++) {
624
+ const target = breaks[i];
625
+ current = t5.blockStatement([
626
+ t5.ifStatement(
627
+ t5.binaryExpression("===", returnResult, t5.stringLiteral(target)),
628
+ t5.blockStatement([t5.breakStatement(t5.identifier(target))]),
629
+ current
630
+ )
631
+ ]);
632
+ }
633
+ if (current) {
634
+ return t5.ifStatement(
635
+ t5.binaryExpression("===", returnType, BREAK_KEY),
636
+ current,
637
+ check
638
+ );
639
+ }
640
+ return check;
641
+ }
642
+ function getContinueCheck(returnType, returnResult, continueCount, continues, check) {
643
+ let current;
644
+ if (continueCount !== continues.length) {
645
+ current = t5.blockStatement([t5.continueStatement()]);
646
+ }
647
+ for (let i = 0, len = continues.length; i < len; i++) {
648
+ const target = continues[i];
649
+ current = t5.blockStatement([
650
+ t5.ifStatement(
651
+ t5.binaryExpression("===", returnResult, t5.stringLiteral(target)),
652
+ t5.blockStatement([t5.continueStatement(t5.identifier(target))]),
653
+ current
654
+ )
655
+ ]);
656
+ }
657
+ if (current) {
658
+ return t5.ifStatement(
659
+ t5.binaryExpression("===", returnType, CONTINUE_KEY),
660
+ current,
661
+ check
662
+ );
663
+ }
664
+ return check;
665
+ }
666
+ function getGeneratorReplacementForServerBlock(path2, registerID, args) {
667
+ const iterator = path2.scope.generateUidIdentifier("iterator");
668
+ const step = path2.scope.generateUidIdentifier("step");
669
+ const replacement = [
670
+ t5.variableDeclaration("let", [
671
+ t5.variableDeclarator(step),
672
+ // First, get the iterator by calling the generator
673
+ t5.variableDeclarator(
674
+ iterator,
675
+ t5.awaitExpression(t5.callExpression(registerID, args))
676
+ )
677
+ ]),
678
+ // Create a while statement, the intent is to
679
+ // repeatedly iterate the generator
680
+ t5.whileStatement(
681
+ t5.booleanLiteral(true),
682
+ t5.blockStatement([
683
+ // Get the next value
684
+ t5.expressionStatement(
685
+ t5.assignmentExpression(
686
+ "=",
687
+ step,
688
+ t5.awaitExpression(
689
+ t5.callExpression(
690
+ t5.memberExpression(iterator, t5.identifier("next")),
691
+ []
692
+ )
693
+ )
694
+ )
695
+ ),
696
+ // Check if the step is done
697
+ t5.ifStatement(
698
+ t5.memberExpression(step, t5.identifier("done")),
699
+ t5.blockStatement([
700
+ // exit the loop
701
+ t5.breakStatement()
702
+ ]),
703
+ // Otherwise, yield the value
704
+ t5.blockStatement([
705
+ t5.expressionStatement(
706
+ t5.yieldExpression(
707
+ t5.memberExpression(step, t5.identifier("value"))
708
+ )
709
+ )
710
+ ])
711
+ )
712
+ ])
713
+ )
714
+ ];
715
+ return [replacement, step];
716
+ }
717
+ function getBlockReplacement(ctx, path2, entryFile, bindings, halting) {
718
+ const returnType = path2.scope.generateUidIdentifier("type");
719
+ const returnResult = path2.scope.generateUidIdentifier("result");
720
+ const returnMutations = path2.scope.generateUidIdentifier("mutations");
721
+ let check;
722
+ if (halting.hasReturn) {
723
+ check = t5.ifStatement(
724
+ t5.binaryExpression("===", returnType, RETURN_KEY),
725
+ t5.blockStatement([t5.returnStatement(returnResult)]),
726
+ check
727
+ );
728
+ }
729
+ if (halting.breakCount > 0) {
730
+ check = getBreakCheck(
731
+ returnType,
732
+ returnResult,
733
+ halting.breakCount,
734
+ halting.breaks,
735
+ check
736
+ );
737
+ }
738
+ if (halting.continueCount > 0) {
739
+ check = getContinueCheck(
740
+ returnType,
741
+ returnResult,
742
+ halting.continueCount,
743
+ halting.continues,
744
+ check
745
+ );
746
+ }
747
+ const replacement = [];
748
+ if (halting.hasYield) {
749
+ const blockID = path2.scope.generateUidIdentifier("block");
750
+ replacement.push(
751
+ t5.variableDeclaration("const", [
752
+ t5.variableDeclarator(
753
+ blockID,
754
+ t5.callExpression(getImportIdentifier(ctx, path2, HIDDEN_GENERATOR), [
755
+ t5.memberExpression(
756
+ t5.awaitExpression(t5.importExpression(t5.stringLiteral(entryFile))),
757
+ t5.identifier("default")
758
+ ),
759
+ bindings.mutations.length ? t5.arrowFunctionExpression(
760
+ [returnMutations],
761
+ t5.assignmentExpression(
762
+ "=",
763
+ t5.objectPattern(
764
+ bindings.mutations.map(
765
+ (item) => t5.objectProperty(item, item, false, true)
766
+ )
767
+ ),
768
+ returnMutations
769
+ )
770
+ ) : t5.nullLiteral()
771
+ ])
772
+ )
773
+ ])
774
+ );
775
+ const [reps, step] = getGeneratorReplacementForServerBlock(
776
+ path2,
777
+ blockID,
778
+ bindings.locals
779
+ );
780
+ for (let i = 0, len = reps.length; i < len; i++) {
781
+ replacement.push(reps[i]);
782
+ }
783
+ replacement.push(
784
+ t5.variableDeclaration("const", [
785
+ t5.variableDeclarator(
786
+ t5.arrayPattern([returnType, returnResult]),
787
+ t5.memberExpression(step, t5.identifier("value"))
788
+ )
789
+ ])
790
+ );
791
+ } else {
792
+ replacement.push(
793
+ t5.variableDeclaration("const", [
794
+ t5.variableDeclarator(
795
+ t5.arrayPattern([returnType, returnResult]),
796
+ t5.awaitExpression(
797
+ t5.callExpression(
798
+ t5.callExpression(getImportIdentifier(ctx, path2, HIDDEN_FUNC), [
799
+ t5.memberExpression(
800
+ t5.awaitExpression(
801
+ t5.importExpression(t5.stringLiteral(entryFile))
802
+ ),
803
+ t5.identifier("default")
804
+ ),
805
+ bindings.mutations.length ? t5.arrowFunctionExpression(
806
+ [returnMutations],
807
+ t5.assignmentExpression(
808
+ "=",
809
+ t5.objectPattern(
810
+ bindings.mutations.map(
811
+ (item) => t5.objectProperty(item, item, false, true)
812
+ )
813
+ ),
814
+ returnMutations
815
+ )
816
+ ) : t5.nullLiteral()
817
+ ]),
818
+ bindings.locals
819
+ )
820
+ )
821
+ )
822
+ ])
823
+ );
824
+ }
825
+ if (check) {
826
+ replacement.push(check);
827
+ }
828
+ return t5.blockStatement(replacement);
829
+ }
830
+ function replaceBlock(ctx, path2, directive, bindings) {
831
+ const halting = transformBlockContent(path2, bindings.mutations);
832
+ const rootFile = createRootFile(
833
+ ctx,
834
+ bindings,
835
+ t5.functionExpression(
836
+ void 0,
837
+ bindings.locals,
838
+ t5.blockStatement(path2.node.body),
839
+ halting.hasYield,
840
+ true
841
+ )
842
+ );
843
+ const entryFile = createEntryFile(ctx, path2, rootFile, directive.target);
844
+ path2.replaceWith(
845
+ getBlockReplacement(ctx, path2, entryFile, bindings, halting)
846
+ );
847
+ }
848
+ function splitBlock(ctx, path2, directive) {
849
+ replaceBlock(
850
+ ctx,
851
+ path2,
852
+ directive,
853
+ extractBindings(
854
+ ctx,
855
+ path2,
856
+ getForeignBindings(path2, "block"),
857
+ directive.pure
858
+ )
859
+ );
860
+ }
861
+ function transformFunctionContent(path2, mutations) {
862
+ const target = path2.scope.getFunctionParent() || path2.scope.getProgramParent();
863
+ const applyMutations = mutations.length ? path2.scope.generateUidIdentifier("mutate") : void 0;
864
+ let hasReturn = false;
865
+ let hasYield = false;
866
+ path2.traverse({
867
+ ReturnStatement(child) {
868
+ const parent = child.scope.getFunctionParent() || child.scope.getProgramParent();
869
+ if (parent === target) {
870
+ hasReturn = true;
871
+ const replacement = [RETURN_KEY];
872
+ if (child.node.argument) {
873
+ replacement.push(child.node.argument);
874
+ } else {
875
+ replacement.push(t5.nullLiteral());
876
+ }
877
+ if (applyMutations) {
878
+ replacement.push(t5.callExpression(applyMutations, []));
879
+ }
880
+ child.replaceWith(t5.returnStatement(t5.arrayExpression(replacement)));
881
+ child.skip();
882
+ }
883
+ },
884
+ YieldExpression(child) {
885
+ const parent = child.scope.getFunctionParent() || child.scope.getProgramParent();
886
+ if (parent === target) {
887
+ hasYield = true;
888
+ }
889
+ }
890
+ });
891
+ const error = path2.scope.generateUidIdentifier("error");
892
+ const throwResult = [THROW_KEY, error];
893
+ const haltResult = [NO_HALT_KEY];
894
+ if (applyMutations) {
895
+ throwResult.push(t5.callExpression(applyMutations, []));
896
+ haltResult.push(t5.nullLiteral());
897
+ haltResult.push(t5.callExpression(applyMutations, []));
898
+ }
899
+ const statements = [
900
+ t5.tryStatement(
901
+ t5.blockStatement(path2.node.body),
902
+ t5.catchClause(
903
+ error,
904
+ t5.blockStatement([t5.returnStatement(t5.arrayExpression(throwResult))])
905
+ )
906
+ ),
907
+ t5.returnStatement(t5.arrayExpression(haltResult))
908
+ ];
909
+ if (applyMutations) {
910
+ statements.unshift(
911
+ t5.variableDeclaration("const", [
912
+ t5.variableDeclarator(
913
+ applyMutations,
914
+ t5.arrowFunctionExpression(
915
+ [],
916
+ t5.objectExpression(
917
+ mutations.map((item) => t5.objectProperty(item, item, false, true))
918
+ )
919
+ )
920
+ )
921
+ ])
922
+ );
923
+ }
924
+ path2.node.body = statements;
925
+ return {
926
+ hasReturn,
927
+ hasYield
928
+ };
929
+ }
930
+ function getFunctionReplacement(ctx, path2, entryFile, bindings, halting) {
931
+ const rest = path2.scope.generateUidIdentifier("rest");
932
+ const returnType = path2.scope.generateUidIdentifier("type");
933
+ const returnResult = path2.scope.generateUidIdentifier("result");
934
+ const returnMutations = path2.scope.generateUidIdentifier("mutations");
935
+ const replacement = [];
936
+ if (halting.hasYield) {
937
+ const funcID = path2.scope.generateUidIdentifier("fn");
938
+ replacement.push(
939
+ t5.variableDeclaration("const", [
940
+ t5.variableDeclarator(
941
+ funcID,
942
+ t5.callExpression(getImportIdentifier(ctx, path2, HIDDEN_GENERATOR), [
943
+ t5.memberExpression(
944
+ t5.awaitExpression(t5.importExpression(t5.stringLiteral(entryFile))),
945
+ t5.identifier("default")
946
+ ),
947
+ bindings.mutations.length ? t5.arrowFunctionExpression(
948
+ [returnMutations],
949
+ t5.assignmentExpression(
950
+ "=",
951
+ t5.objectPattern(
952
+ bindings.mutations.map(
953
+ (item) => t5.objectProperty(item, item, false, true)
954
+ )
955
+ ),
956
+ returnMutations
957
+ )
958
+ ) : t5.nullLiteral()
959
+ ])
960
+ )
961
+ ])
962
+ );
963
+ const [reps, step] = getGeneratorReplacementForServerBlock(path2, funcID, [
964
+ t5.arrayExpression(bindings.locals),
965
+ t5.spreadElement(rest)
966
+ ]);
967
+ for (let i = 0, len = reps.length; i < len; i++) {
968
+ replacement.push(reps[i]);
969
+ }
970
+ replacement.push(
971
+ t5.variableDeclaration("const", [
972
+ t5.variableDeclarator(
973
+ t5.arrayPattern([returnType, returnResult]),
974
+ t5.memberExpression(step, t5.identifier("value"))
975
+ )
976
+ ])
977
+ );
978
+ } else {
979
+ replacement.push(
980
+ t5.variableDeclaration("const", [
981
+ t5.variableDeclarator(
982
+ t5.arrayPattern([returnType, returnResult]),
983
+ t5.awaitExpression(
984
+ t5.callExpression(
985
+ t5.callExpression(getImportIdentifier(ctx, path2, HIDDEN_FUNC), [
986
+ t5.memberExpression(
987
+ t5.awaitExpression(
988
+ t5.importExpression(t5.stringLiteral(entryFile))
989
+ ),
990
+ t5.identifier("default")
991
+ ),
992
+ bindings.mutations.length ? t5.arrowFunctionExpression(
993
+ [returnMutations],
994
+ t5.assignmentExpression(
995
+ "=",
996
+ t5.objectPattern(
997
+ bindings.mutations.map(
998
+ (item) => t5.objectProperty(item, item, false, true)
999
+ )
1000
+ ),
1001
+ returnMutations
1002
+ )
1003
+ ) : t5.nullLiteral()
1004
+ ]),
1005
+ [t5.arrayExpression(bindings.locals), t5.spreadElement(rest)]
1006
+ )
1007
+ )
1008
+ )
1009
+ ])
1010
+ );
1011
+ }
1012
+ replacement.push(t5.returnStatement(returnResult));
1013
+ if (isPathValid(path2, t5.isFunctionExpression)) {
1014
+ return t5.functionExpression(
1015
+ path2.node.id,
1016
+ [t5.restElement(rest)],
1017
+ t5.blockStatement(replacement),
1018
+ true,
1019
+ halting.hasYield
1020
+ );
1021
+ }
1022
+ return t5.arrowFunctionExpression(
1023
+ [t5.restElement(rest)],
1024
+ t5.blockStatement(replacement),
1025
+ true
1026
+ );
1027
+ }
1028
+ function replaceFunction(ctx, path2, func, bindings) {
1029
+ const body = path2.get("body");
1030
+ if (isPathValid(body, t5.isExpression)) {
1031
+ body.replaceWith(t5.blockStatement([t5.returnStatement(body.node)]));
1032
+ }
1033
+ assert(isPathValid(body, t5.isBlockStatement), "invariant");
1034
+ const halting = transformFunctionContent(body, bindings.mutations);
1035
+ const rootFile = createRootFile(
1036
+ ctx,
1037
+ bindings,
1038
+ t5.isFunctionExpression(path2.node) ? t5.functionExpression(
1039
+ path2.node.id,
1040
+ [t5.arrayPattern(bindings.locals), ...path2.node.params],
1041
+ path2.node.body,
1042
+ path2.node.async,
1043
+ path2.node.generator
1044
+ ) : t5.arrowFunctionExpression(
1045
+ [t5.arrayPattern(bindings.locals), ...path2.node.params],
1046
+ path2.node.body,
1047
+ path2.node.async
1048
+ )
1049
+ );
1050
+ const entryFile = createEntryFile(ctx, path2, rootFile, func.target);
1051
+ return getFunctionReplacement(ctx, path2, entryFile, bindings, halting);
1052
+ }
1053
+ function splitFunction(ctx, path2, func) {
1054
+ return replaceFunction(
1055
+ ctx,
1056
+ path2,
1057
+ func,
1058
+ extractBindings(ctx, path2, getForeignBindings(path2, "function"), func.pure)
1059
+ );
1060
+ }
1061
+ function replaceExpression(ctx, path2, func, bindings) {
1062
+ const rootFile = createRootFile(ctx, bindings, path2.node);
1063
+ const entryFile = createEntryFile(ctx, path2, rootFile, func.target);
1064
+ const rest = path2.scope.generateUidIdentifier("rest");
1065
+ return t5.arrowFunctionExpression(
1066
+ [t5.restElement(rest)],
1067
+ t5.callExpression(
1068
+ t5.memberExpression(
1069
+ t5.awaitExpression(t5.importExpression(t5.stringLiteral(entryFile))),
1070
+ t5.identifier("default")
1071
+ ),
1072
+ [t5.spreadElement(rest)]
1073
+ ),
1074
+ true
1075
+ );
1076
+ }
1077
+ function splitExpression(ctx, path2, func) {
1078
+ return replaceExpression(
1079
+ ctx,
1080
+ path2,
1081
+ func,
1082
+ extractBindings(
1083
+ ctx,
1084
+ path2,
1085
+ getForeignBindings(path2, "expression"),
1086
+ func.pure
1087
+ )
1088
+ );
1089
+ }
1090
+
1091
+ // src/transform-block.ts
1092
+ function getValidDirectiveFromString(ctx, string) {
1093
+ for (let i = 0, len = ctx.options.directives.length; i < len; i++) {
1094
+ const current = ctx.options.directives[i];
1095
+ if (current.value === string) {
1096
+ return current;
1097
+ }
1098
+ }
1099
+ return void 0;
1100
+ }
1101
+ function getDefinitionFromDirectives(ctx, path2) {
1102
+ for (let i = 0, len = path2.node.directives.length; i < len; i++) {
1103
+ const statement = path2.node.directives[i].value.value;
1104
+ const directive = getValidDirectiveFromString(ctx, statement);
1105
+ if (directive) {
1106
+ return directive;
1107
+ }
1108
+ }
1109
+ return void 0;
1110
+ }
1111
+ function getDefinitionFromFauxDirectives(ctx, path2) {
1112
+ for (let i = 0, len = path2.node.body.length; i < len; i++) {
1113
+ const statement = path2.node.body[i];
1114
+ if (statement.type === "ExpressionStatement" && statement.expression.type === "StringLiteral") {
1115
+ const directive = getValidDirectiveFromString(
1116
+ ctx,
1117
+ statement.expression.value
1118
+ );
1119
+ if (directive) {
1120
+ return directive;
1121
+ }
1122
+ } else {
1123
+ break;
1124
+ }
1125
+ }
1126
+ return void 0;
1127
+ }
1128
+ function getDirectiveDefinitionFromBlock(ctx, path2) {
1129
+ const parent = path2.getFunctionParent();
1130
+ if (parent && !parent.node.async) {
1131
+ return void 0;
1132
+ }
1133
+ return getDefinitionFromDirectives(ctx, path2) || getDefinitionFromFauxDirectives(ctx, path2);
1134
+ }
1135
+ function cleanBlockForDirectives(path2, definition) {
1136
+ const newDirectives = [];
1137
+ for (let i = 0, len = path2.node.directives.length; i < len; i++) {
1138
+ const current = path2.node.directives[i];
1139
+ if (current.value.value !== definition.value) {
1140
+ newDirectives.push(current);
1141
+ }
1142
+ }
1143
+ path2.node.directives = newDirectives;
1144
+ }
1145
+ function cleanBlockForFauxDirectives(path2, definition) {
1146
+ const body = path2.get("body");
1147
+ for (let i = 0, len = body.length; i < len; i++) {
1148
+ const statement = body[i];
1149
+ if (statement.node.type === "ExpressionStatement" && statement.node.expression.type === "StringLiteral") {
1150
+ if (statement.node.expression.value === definition.value) {
1151
+ statement.remove();
1152
+ return;
1153
+ }
1154
+ }
1155
+ }
1156
+ }
1157
+ function transformBlock(ctx, path2) {
1158
+ const definition = getDirectiveDefinitionFromBlock(ctx, path2);
1159
+ if (!definition) {
1160
+ return;
1161
+ }
1162
+ cleanBlockForDirectives(path2, definition);
1163
+ cleanBlockForFauxDirectives(path2, definition);
1164
+ splitBlock(ctx, path2, definition);
1165
+ }
1166
+
1167
+ // src/transform-call.ts
1168
+ import * as t6 from "@babel/types";
1169
+ function getFunctionDefinitionFromPropName(definitions, propName) {
1170
+ for (let i = 0, len = definitions.length; i < len; i++) {
1171
+ const def = definitions[i];
1172
+ if (def.source.kind === "default" && propName === "default") {
1173
+ return def;
1174
+ }
1175
+ if (def.source.kind === "named" && propName === def.source.name) {
1176
+ return def;
1177
+ }
1178
+ }
1179
+ return void 0;
1180
+ }
1181
+ function getFunctionDefinitionFromCallee(ctx, path2) {
1182
+ const callee = path2.node.callee;
1183
+ const id = unwrapNode(callee, t6.isIdentifier);
1184
+ if (id) {
1185
+ const binding = path2.scope.getBindingIdentifier(id.name);
1186
+ if (binding) {
1187
+ return ctx.registrations.identifiers.get(binding);
1188
+ }
1189
+ return void 0;
1190
+ }
1191
+ const memberExpr = unwrapNode(callee, t6.isMemberExpression);
1192
+ if (memberExpr && !memberExpr.computed && t6.isIdentifier(memberExpr.property)) {
1193
+ const object = unwrapNode(memberExpr.object, t6.isIdentifier);
1194
+ if (object) {
1195
+ const binding = path2.scope.getBindingIdentifier(object.name);
1196
+ if (binding) {
1197
+ const definitions = ctx.registrations.namespaces.get(binding);
1198
+ if (definitions) {
1199
+ return getFunctionDefinitionFromPropName(
1200
+ definitions,
1201
+ memberExpr.property.name
1202
+ );
1203
+ }
1204
+ }
1205
+ }
1206
+ }
1207
+ return void 0;
1208
+ }
1209
+ function isValidFunction(node) {
1210
+ return t6.isArrowFunctionExpression(node) || t6.isFunctionExpression(node);
1211
+ }
1212
+ function isSkippableFunction(node) {
1213
+ if (node.leadingComments) {
1214
+ for (let i = 0, len = node.leadingComments.length; i < len; i++) {
1215
+ if (/^@dismantle skip$/.test(node.leadingComments[i].value)) {
1216
+ return true;
1217
+ }
1218
+ }
1219
+ }
1220
+ return false;
1221
+ }
1222
+ function transformCall(ctx, path2) {
1223
+ const definition = getFunctionDefinitionFromCallee(ctx, path2);
1224
+ if (!definition) {
1225
+ return;
1226
+ }
1227
+ const args = path2.get("arguments");
1228
+ const expr = args[0];
1229
+ if (isPathValid(expr, t6.isExpression)) {
1230
+ if (isSkippableFunction(expr.node)) {
1231
+ return;
1232
+ }
1233
+ const replacement = isPathValid(expr, isValidFunction) ? splitFunction(ctx, expr, definition) : splitExpression(ctx, expr, definition);
1234
+ if (definition.preserve) {
1235
+ expr.replaceWith(t6.addComment(replacement, "leading", "@dismantle skip"));
1236
+ } else {
1237
+ path2.replaceWith(replacement);
1238
+ }
1239
+ }
1240
+ }
1241
+
1242
+ // src/utils/register-import-specifiers.ts
1243
+ import * as t7 from "@babel/types";
1244
+ function registerImportSpecifier(ctx, node, definition) {
1245
+ if (t7.isImportSpecifier(node)) {
1246
+ if (node.importKind === "type" || node.importKind === "typeof") {
1247
+ return;
1248
+ }
1249
+ const key = getImportSpecifierName(node);
1250
+ if (definition.source.kind === "named" && key === definition.source.name || definition.source.kind === "default" && key === "default") {
1251
+ ctx.registrations.identifiers.set(node.local, definition);
1252
+ }
1253
+ }
1254
+ if (t7.isImportDefaultSpecifier(node) && definition.source.kind === "default") {
1255
+ ctx.registrations.identifiers.set(node.local, definition);
1256
+ }
1257
+ if (t7.isImportNamespaceSpecifier(node)) {
1258
+ let current = ctx.registrations.namespaces.get(node.local);
1259
+ if (!current) {
1260
+ current = [];
1261
+ }
1262
+ current.push(definition);
1263
+ ctx.registrations.namespaces.set(node.local, current);
1264
+ }
1265
+ }
1266
+ function registerImportDeclarationByDefinition(ctx, path2, definition) {
1267
+ for (let i = 0, len = path2.node.specifiers.length; i < len; i++) {
1268
+ const specifier = path2.node.specifiers[i];
1269
+ registerImportSpecifier(ctx, specifier, definition);
1270
+ }
1271
+ }
1272
+ function registerImportSpecifiers(ctx, programPath) {
1273
+ const len = ctx.options.functions.length;
1274
+ if (!len) {
1275
+ return;
1276
+ }
1277
+ programPath.traverse({
1278
+ ImportDeclaration(path2) {
1279
+ if (path2.node.importKind === "type" || path2.node.importKind === "typeof") {
1280
+ return;
1281
+ }
1282
+ for (let i = 0; i < len; i++) {
1283
+ const func = ctx.options.functions[i];
1284
+ if (func.source.source === path2.node.source.value) {
1285
+ registerImportDeclarationByDefinition(ctx, path2, func);
1286
+ }
1287
+ }
1288
+ }
1289
+ });
1290
+ }
1291
+
1292
+ // src/plugin.ts
1293
+ function plugin() {
1294
+ return {
1295
+ name: "dismantle",
1296
+ visitor: {
1297
+ Program(path2, ctx) {
1298
+ registerImportSpecifiers(ctx.opts, path2);
1299
+ },
1300
+ BlockStatement(path2, ctx) {
1301
+ transformBlock(ctx.opts, path2);
1302
+ },
1303
+ CallExpression(path2, ctx) {
1304
+ transformCall(ctx.opts, path2);
1305
+ }
1306
+ }
1307
+ };
1308
+ }
1309
+
1310
+ // src/utils/xxhash32.ts
1311
+ var PRIME32_1 = 2654435761;
1312
+ var PRIME32_2 = 2246822519;
1313
+ var PRIME32_3 = 3266489917;
1314
+ var PRIME32_4 = 668265263;
1315
+ var PRIME32_5 = 374761393;
1316
+ function toUtf8(text) {
1317
+ const bytes = [];
1318
+ for (let i = 0, n = text.length; i < n; ++i) {
1319
+ const c = text.charCodeAt(i);
1320
+ if (c < 128) {
1321
+ bytes.push(c);
1322
+ } else if (c < 2048) {
1323
+ bytes.push(192 | c >> 6, 128 | c & 63);
1324
+ } else if (c < 55296 || c >= 57344) {
1325
+ bytes.push(224 | c >> 12, 128 | c >> 6 & 63, 128 | c & 63);
1326
+ } else {
1327
+ const cp = 65536 + ((c & 1023) << 10 | text.charCodeAt(++i) & 1023);
1328
+ bytes.push(
1329
+ 240 | cp >> 18 & 7,
1330
+ 128 | cp >> 12 & 63,
1331
+ 128 | cp >> 6 & 63,
1332
+ 128 | cp & 63
1333
+ );
1334
+ }
1335
+ }
1336
+ return new Uint8Array(bytes);
1337
+ }
1338
+ function xxHash32(buffer, seed = 0) {
1339
+ buffer = typeof buffer === "string" ? toUtf8(buffer) : buffer;
1340
+ const b = buffer;
1341
+ let acc = seed + PRIME32_5 & 4294967295;
1342
+ let offset = 0;
1343
+ if (b.length >= 16) {
1344
+ const accN = [
1345
+ seed + PRIME32_1 + PRIME32_2 & 4294967295,
1346
+ seed + PRIME32_2 & 4294967295,
1347
+ seed + 0 & 4294967295,
1348
+ seed - PRIME32_1 & 4294967295
1349
+ ];
1350
+ const b2 = buffer;
1351
+ const limit2 = b2.length - 16;
1352
+ let lane = 0;
1353
+ for (offset = 0; (offset & 4294967280) <= limit2; offset += 4) {
1354
+ const i = offset;
1355
+ const laneN0 = b2[i + 0] + (b2[i + 1] << 8);
1356
+ const laneN1 = b2[i + 2] + (b2[i + 3] << 8);
1357
+ const laneNP = laneN0 * PRIME32_2 + (laneN1 * PRIME32_2 << 16);
1358
+ let acc2 = accN[lane] + laneNP & 4294967295;
1359
+ acc2 = acc2 << 13 | acc2 >>> 19;
1360
+ const acc0 = acc2 & 65535;
1361
+ const acc1 = acc2 >>> 16;
1362
+ accN[lane] = acc0 * PRIME32_1 + (acc1 * PRIME32_1 << 16) & 4294967295;
1363
+ lane = lane + 1 & 3;
1364
+ }
1365
+ acc = (accN[0] << 1 | accN[0] >>> 31) + (accN[1] << 7 | accN[1] >>> 25) + (accN[2] << 12 | accN[2] >>> 20) + (accN[3] << 18 | accN[3] >>> 14) & 4294967295;
1366
+ }
1367
+ acc = acc + buffer.length & 4294967295;
1368
+ const limit = buffer.length - 4;
1369
+ for (; offset <= limit; offset += 4) {
1370
+ const i = offset;
1371
+ const laneN0 = b[i + 0] + (b[i + 1] << 8);
1372
+ const laneN1 = b[i + 2] + (b[i + 3] << 8);
1373
+ const laneP = laneN0 * PRIME32_3 + (laneN1 * PRIME32_3 << 16);
1374
+ acc = acc + laneP & 4294967295;
1375
+ acc = acc << 17 | acc >>> 15;
1376
+ acc = (acc & 65535) * PRIME32_4 + ((acc >>> 16) * PRIME32_4 << 16) & 4294967295;
1377
+ }
1378
+ for (; offset < b.length; ++offset) {
1379
+ const lane = b[offset];
1380
+ acc += lane * PRIME32_5;
1381
+ acc = acc << 11 | acc >>> 21;
1382
+ acc = (acc & 65535) * PRIME32_1 + ((acc >>> 16) * PRIME32_1 << 16) & 4294967295;
1383
+ }
1384
+ acc ^= acc >>> 15;
1385
+ acc = ((acc & 65535) * PRIME32_2 & 4294967295) + ((acc >>> 16) * PRIME32_2 << 16);
1386
+ acc ^= acc >>> 13;
1387
+ acc = ((acc & 65535) * PRIME32_3 & 4294967295) + ((acc >>> 16) * PRIME32_3 << 16);
1388
+ acc ^= acc >>> 16;
1389
+ return acc < 0 ? acc + 4294967296 : acc;
1390
+ }
1391
+
1392
+ // src/index.ts
1393
+ async function compile(id, code, options) {
1394
+ const parsedPath = path.parse(id);
1395
+ const entries = [];
1396
+ const roots = [];
1397
+ const files = /* @__PURE__ */ new Map();
1398
+ const ctx = {
1399
+ id,
1400
+ path: parsedPath,
1401
+ imports: /* @__PURE__ */ new Map(),
1402
+ virtual: {
1403
+ count: 0
1404
+ },
1405
+ options,
1406
+ bindings: /* @__PURE__ */ new Map(),
1407
+ blocks: {
1408
+ hash: xxHash32(id).toString(16),
1409
+ count: 0
1410
+ },
1411
+ onVirtualFile(current, content, mode) {
1412
+ const filePath = path.join(parsedPath.dir, current);
1413
+ files.set(path.join(parsedPath.dir, current), content);
1414
+ if (mode === "entry") {
1415
+ entries.push(filePath);
1416
+ } else if (mode === "root") {
1417
+ roots.push(filePath);
1418
+ }
1419
+ },
1420
+ registrations: {
1421
+ identifiers: /* @__PURE__ */ new Map(),
1422
+ namespaces: /* @__PURE__ */ new Map()
1423
+ }
1424
+ };
1425
+ const plugins = ["jsx"];
1426
+ if (/\.[mc]?tsx?$/i.test(id)) {
1427
+ plugins.push("typescript");
1428
+ }
1429
+ const result = await babel.transformAsync(code, {
1430
+ plugins: [[plugin, ctx]],
1431
+ parserOpts: {
1432
+ plugins
1433
+ },
1434
+ filename: parsedPath.base,
1435
+ ast: false,
1436
+ sourceFileName: id,
1437
+ sourceMaps: true,
1438
+ configFile: false,
1439
+ babelrc: false
1440
+ });
1441
+ assert(result, "invariant");
1442
+ return {
1443
+ code: result.code,
1444
+ map: result.map,
1445
+ files,
1446
+ entries,
1447
+ roots
1448
+ };
1449
+ }
1450
+ export {
1451
+ compile
1452
+ };
1453
+ //# sourceMappingURL=runtime.mjs.map