@rhinostone/swig 2.0.1 → 2.1.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/dist/swig.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! Swig v2.0.1 | https://github.com/gina-io/swig | @license https://github.com/gina-io/swig/blob/master/LICENSE */
1
+ /*! Swig v2.1.0 | https://github.com/gina-io/swig | @license https://github.com/gina-io/swig/blob/master/LICENSE */
2
2
  /*! DateZ (c) 2011 Tomo Universalis | @license https://github.com/ocrybit/DateZ/blob/master/LISENCE */
3
3
  (() => {
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -275,6 +275,49 @@
275
275
  exports.legacyJS = function(js, loc) {
276
276
  return withLoc({ type: "LegacyJS", js }, loc);
277
277
  };
278
+ exports.extendsDeferred = function(path, childBlocks, childIRs, resolveFrom, loc) {
279
+ var node = { type: "ExtendsDeferred", path };
280
+ if (childBlocks !== void 0) {
281
+ node.childBlocks = childBlocks;
282
+ }
283
+ if (childIRs !== void 0) {
284
+ node.childIRs = childIRs;
285
+ }
286
+ if (resolveFrom !== void 0) {
287
+ node.resolveFrom = resolveFrom;
288
+ }
289
+ return withLoc(node, loc);
290
+ };
291
+ exports.includeDeferred = function(path, context, isolated, ignoreMissing, resolveFrom, loc) {
292
+ var node = { type: "IncludeDeferred", path };
293
+ if (context !== void 0) {
294
+ node.context = context;
295
+ }
296
+ if (isolated !== void 0) {
297
+ node.isolated = isolated;
298
+ }
299
+ if (ignoreMissing !== void 0) {
300
+ node.ignoreMissing = ignoreMissing;
301
+ }
302
+ if (resolveFrom !== void 0) {
303
+ node.resolveFrom = resolveFrom;
304
+ }
305
+ return withLoc(node, loc);
306
+ };
307
+ exports.importDeferred = function(path, alias, resolveFrom, loc) {
308
+ var node = { type: "ImportDeferred", path, alias };
309
+ if (resolveFrom !== void 0) {
310
+ node.resolveFrom = resolveFrom;
311
+ }
312
+ return withLoc(node, loc);
313
+ };
314
+ exports.fromImportDeferred = function(path, imports, resolveFrom, loc) {
315
+ var node = { type: "FromImportDeferred", path, imports };
316
+ if (resolveFrom !== void 0) {
317
+ node.resolveFrom = resolveFrom;
318
+ }
319
+ return withLoc(node, loc);
320
+ };
278
321
  exports.literal = function(kind, value, loc) {
279
322
  return withLoc({ type: "Literal", kind, value }, loc);
280
323
  };
@@ -1345,6 +1388,12 @@
1345
1388
  macroIndexOfJS = '"' + macroParams.join('","') + '"';
1346
1389
  }
1347
1390
  out += "_ctx." + node.name + " = function (" + macroSigJS + ') {\n var _output = "",\n __ctx = _utils.extend({}, _ctx);\n _utils.each(_ctx, function (v, k) {\n if ([' + macroIndexOfJS + "].indexOf(k) !== -1) { delete _ctx[k]; }\n });\n" + macroBodyJS + "\n _ctx = _utils.extend(_ctx, __ctx);\n return _output;\n};\n_ctx." + node.name + ".safe = true;\n";
1391
+ if (options && options.codegenMode === "async") {
1392
+ if (_security.dangerousProps.indexOf(node.name) !== -1) {
1393
+ throw new Error('Macro name "' + node.name + '" is reserved.');
1394
+ }
1395
+ out += "_exports." + node.name + " = _ctx." + node.name + ";\n";
1396
+ }
1348
1397
  return;
1349
1398
  }
1350
1399
  if (node.type === "Parent") {
@@ -1361,6 +1410,24 @@
1361
1410
  return;
1362
1411
  }
1363
1412
  if (node.type === "Block") {
1413
+ if (options && options.codegenMode === "async") {
1414
+ var blockNameJS = JSON.stringify(node.name);
1415
+ out += "if (_blocks && _blocks[" + blockNameJS + "]) {\n";
1416
+ out += " _output += await _blocks[" + blockNameJS + "](_ctx);\n";
1417
+ out += "} else {\n";
1418
+ utils.each(node.body, function(b) {
1419
+ if (b.type === "LegacyJS") {
1420
+ out += b.js;
1421
+ return;
1422
+ }
1423
+ if (b.type === "Text" || b.type === "Raw") {
1424
+ out += '_output += "' + escapeTextValue(b.value) + '";\n';
1425
+ return;
1426
+ }
1427
+ });
1428
+ out += "}\n";
1429
+ return;
1430
+ }
1364
1431
  utils.each(node.body, function(b) {
1365
1432
  if (b.type === "LegacyJS") {
1366
1433
  out += b.js;
@@ -1398,6 +1465,106 @@
1398
1465
  out += (node.ignoreMissing ? " try {\n" : "") + "_output += _swig.compileFile(" + incPathJS + ', {resolveFrom: "' + node.resolveFrom + '"})(' + incSelector + ");\n" + (node.ignoreMissing ? "} catch (e) {}\n" : "");
1399
1466
  return;
1400
1467
  }
1468
+ if (node.type === "IncludeDeferred") {
1469
+ var incdPathJS, incdCtxJS;
1470
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1471
+ incdPathJS = exports.emitExpr(node.path);
1472
+ } else {
1473
+ incdPathJS = node.path;
1474
+ }
1475
+ if (node.context !== void 0) {
1476
+ if (typeof node.context === "object" && typeof node.context.type === "string") {
1477
+ incdCtxJS = exports.emitExpr(node.context);
1478
+ } else {
1479
+ incdCtxJS = node.context;
1480
+ }
1481
+ }
1482
+ var incdSelector;
1483
+ if (node.isolated && incdCtxJS) {
1484
+ incdSelector = incdCtxJS;
1485
+ } else if (!incdCtxJS) {
1486
+ incdSelector = "_ctx";
1487
+ } else {
1488
+ incdSelector = "_utils.extend({}, _ctx, " + incdCtxJS + ")";
1489
+ }
1490
+ var incdOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1491
+ out += (node.ignoreMissing ? " try {\n" : "") + "_output += (await (await _swig.getTemplate(" + incdPathJS + ", " + incdOpts + "))(" + incdSelector + ")).output;\n" + (node.ignoreMissing ? "} catch (e) {}\n" : "");
1492
+ return;
1493
+ }
1494
+ if (node.type === "ImportDeferred") {
1495
+ if (_security.dangerousProps.indexOf(node.alias) !== -1) {
1496
+ throw new Error('Import alias "' + node.alias + '" is reserved.');
1497
+ }
1498
+ var impdPathJS;
1499
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1500
+ impdPathJS = exports.emitExpr(node.path);
1501
+ } else {
1502
+ impdPathJS = node.path;
1503
+ }
1504
+ var impdOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1505
+ out += "_ctx." + node.alias + " = (await (await _swig.getTemplate(" + impdPathJS + ", " + impdOpts + "))(_ctx)).exports;\n";
1506
+ return;
1507
+ }
1508
+ if (node.type === "FromImportDeferred") {
1509
+ var fromdImports = node.imports || [];
1510
+ utils.each(fromdImports, function(entry) {
1511
+ if (_security.dangerousProps.indexOf(entry.name) !== -1) {
1512
+ throw new Error('From-import name "' + entry.name + '" is reserved.');
1513
+ }
1514
+ var bindName = entry.alias || entry.name;
1515
+ if (_security.dangerousProps.indexOf(bindName) !== -1) {
1516
+ throw new Error('From-import binding "' + bindName + '" is reserved.');
1517
+ }
1518
+ });
1519
+ var fromdPathJS;
1520
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1521
+ fromdPathJS = exports.emitExpr(node.path);
1522
+ } else {
1523
+ fromdPathJS = node.path;
1524
+ }
1525
+ var fromdOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1526
+ var fromdBindings = "";
1527
+ utils.each(fromdImports, function(entry) {
1528
+ var bindName = entry.alias || entry.name;
1529
+ fromdBindings += " _ctx." + bindName + ' = _imp["' + entry.name + '"];\n';
1530
+ });
1531
+ out += "await (async function () {\n var _imp = (await (await _swig.getTemplate(" + fromdPathJS + ", " + fromdOpts + "))(_ctx)).exports;\n" + fromdBindings + "})();\n";
1532
+ return;
1533
+ }
1534
+ if (node.type === "ExtendsDeferred") {
1535
+ if (node.childIRs && node.childIRs.length) {
1536
+ out += exports.compile(node.childIRs, parents, options);
1537
+ }
1538
+ out += "var _localChildBlocks = {};\n";
1539
+ if (node.childBlocks) {
1540
+ utils.each(node.childBlocks, function(block, name) {
1541
+ var blockBodyJS = "";
1542
+ utils.each(block.body, function(b) {
1543
+ if (b.type === "LegacyJS") {
1544
+ blockBodyJS += b.js;
1545
+ return;
1546
+ }
1547
+ if (b.type === "Text" || b.type === "Raw") {
1548
+ blockBodyJS += '_output += "' + escapeTextValue(b.value) + '";\n';
1549
+ return;
1550
+ }
1551
+ });
1552
+ out += "_localChildBlocks[" + JSON.stringify(name) + '] = async function (_ctx) {\n var _output = "";\n' + blockBodyJS + " return _output;\n};\n";
1553
+ });
1554
+ }
1555
+ out += "var _mergedBlocks = _utils.extend({}, _localChildBlocks, _blocks || {});\n";
1556
+ var extPathJS;
1557
+ if (node.path && typeof node.path === "object" && typeof node.path.type === "string") {
1558
+ extPathJS = exports.emitExpr(node.path);
1559
+ } else {
1560
+ extPathJS = node.path;
1561
+ }
1562
+ var extOpts = '{resolveFrom: "' + (node.resolveFrom || "") + '"}';
1563
+ out += "var _parentTpl = await _swig.getTemplate(" + extPathJS + ", " + extOpts + ");\n";
1564
+ out += "var _parentResult = await _parentTpl(_ctx, _mergedBlocks);\n";
1565
+ out += "_output = _parentResult.output;\n";
1566
+ return;
1567
+ }
1401
1568
  if (node.type === "With") {
1402
1569
  var withCtxJS;
1403
1570
  if (node.context !== void 0) {
@@ -1575,12 +1742,8 @@
1575
1742
  return build;
1576
1743
  }
1577
1744
  function checkMatchExpr(match) {
1578
- var result;
1579
- function buildDot(ctx) {
1580
- return "(" + checkDotExpr(match, ctx) + " ? " + ctx + match.join(".") + ' : "")';
1581
- }
1582
- result = "(" + checkDotExpr(match, "_ctx.") + " ? " + buildDot("_ctx.") + " : " + buildDot("") + ")";
1583
- return "(" + result + " !== null ? " + result + ' : "" )';
1745
+ var leaf = match.join(".");
1746
+ return "(" + checkDotExpr(match, "_ctx.") + " ? _ctx." + leaf + " : (" + checkDotExpr(match, "") + " ? " + leaf + ' : ""))';
1584
1747
  }
1585
1748
  function emitAccess(node, d) {
1586
1749
  if (node.key && node.key.type === "Literal" && node.key.kind === "string") {
@@ -2652,7 +2815,7 @@
2652
2815
  * @private
2653
2816
  */
2654
2817
  checkMatch: function(match) {
2655
- var temp = match[0], result;
2818
+ var temp = match[0], leaf = match.join(".");
2656
2819
  function checkDot(ctx) {
2657
2820
  var c = ctx + temp, m = match, build = "";
2658
2821
  build = "(typeof " + c + ' !== "undefined" && ' + c + " !== null";
@@ -2666,11 +2829,7 @@
2666
2829
  build += ")";
2667
2830
  return build;
2668
2831
  }
2669
- function buildDot(ctx) {
2670
- return "(" + checkDot(ctx) + " ? " + ctx + match.join(".") + ' : "")';
2671
- }
2672
- result = "(" + checkDot("_ctx.") + " ? " + buildDot("_ctx.") + " : " + buildDot("") + ")";
2673
- return "(" + result + " !== null ? " + result + ' : "" )';
2832
+ return "(" + checkDot("_ctx.") + " ? _ctx." + leaf + " : (" + checkDot("") + " ? " + leaf + ' : ""))';
2674
2833
  }
2675
2834
  };
2676
2835
  exports.TokenParser = TokenParser;
@@ -3789,6 +3948,155 @@
3789
3948
  }
3790
3949
  });
3791
3950
 
3951
+ // lib/async/pre-walker.js
3952
+ var require_pre_walker = __commonJS({
3953
+ "lib/async/pre-walker.js"(exports) {
3954
+ var utils = require_utils2();
3955
+ function escapeRegExp(str) {
3956
+ return str.replace(/[\-\/\\\^$*+?.()|\[\]{}]/g, "\\$&");
3957
+ }
3958
+ function buildSplitter(controls) {
3959
+ var anyChar = "[\\s\\S]*?", varOpen = escapeRegExp(controls.varControls[0]), varClose = escapeRegExp(controls.varControls[1]), tagOpen = escapeRegExp(controls.tagControls[0]), tagClose = escapeRegExp(controls.tagControls[1]), cmtOpen = escapeRegExp(controls.cmtControls[0]), cmtClose = escapeRegExp(controls.cmtControls[1]);
3960
+ return new RegExp(
3961
+ "(" + tagOpen + anyChar + tagClose + "|" + varOpen + anyChar + varClose + "|" + cmtOpen + anyChar + cmtClose + ")"
3962
+ );
3963
+ }
3964
+ function stripTagBody(chunk, tagOpen, tagClose) {
3965
+ var body = chunk.substr(tagOpen.length, chunk.length - tagOpen.length - tagClose.length);
3966
+ if (body.charAt(0) === "-") {
3967
+ body = body.substr(1);
3968
+ }
3969
+ if (body.charAt(body.length - 1) === "-") {
3970
+ body = body.substr(0, body.length - 1);
3971
+ }
3972
+ return body.replace(/^\s+|\s+$/g, "");
3973
+ }
3974
+ exports.scan = function(source, opts) {
3975
+ source = source.replace(/\r\n/g, "\n");
3976
+ var splitter = buildSplitter(opts), tagOpen = opts.tagControls[0], tagClose = opts.tagControls[1], rawTag = opts.rawTag, endRawTag = "end" + rawTag, keywordRegex = new RegExp(
3977
+ "^(" + opts.keywords.join("|") + `)\\s+["\\']([^"\\']+)["\\']`
3978
+ ), chunks = source.split(splitter), results = [], inRaw = false, i, chunk, body, name, m;
3979
+ for (i = 0; i < chunks.length; i += 1) {
3980
+ chunk = chunks[i];
3981
+ if (typeof chunk !== "string" || !chunk) {
3982
+ continue;
3983
+ }
3984
+ if (!utils.startsWith(chunk, tagOpen) || !utils.endsWith(chunk, tagClose)) {
3985
+ continue;
3986
+ }
3987
+ body = stripTagBody(chunk, tagOpen, tagClose);
3988
+ name = body.split(/\s+/)[0];
3989
+ if (name === rawTag) {
3990
+ inRaw = true;
3991
+ continue;
3992
+ }
3993
+ if (name === endRawTag) {
3994
+ inRaw = false;
3995
+ continue;
3996
+ }
3997
+ if (inRaw) {
3998
+ continue;
3999
+ }
4000
+ m = keywordRegex.exec(body);
4001
+ if (m) {
4002
+ results.push({ kind: m[1], path: m[2] });
4003
+ }
4004
+ }
4005
+ return results;
4006
+ };
4007
+ exports.walk = function(entryPath, loader, scanOpts) {
4008
+ var memMap = {};
4009
+ var pending = {};
4010
+ return new Promise(function(resolve, reject) {
4011
+ var inFlight = 0;
4012
+ var queue = [];
4013
+ var hasError = false;
4014
+ function enqueue(path) {
4015
+ if (memMap.hasOwnProperty(path) || pending[path]) {
4016
+ return;
4017
+ }
4018
+ pending[path] = true;
4019
+ queue.push(path);
4020
+ }
4021
+ function drain() {
4022
+ while (queue.length > 0 && !hasError) {
4023
+ var path = queue.shift();
4024
+ inFlight += 1;
4025
+ startLoad(path);
4026
+ }
4027
+ if (inFlight === 0 && !hasError && queue.length === 0) {
4028
+ resolve(memMap);
4029
+ }
4030
+ }
4031
+ function startLoad(resolvedPath) {
4032
+ loader.load(resolvedPath, function(err, src) {
4033
+ if (hasError) {
4034
+ return;
4035
+ }
4036
+ if (err) {
4037
+ hasError = true;
4038
+ reject(err);
4039
+ return;
4040
+ }
4041
+ if (typeof src !== "string") {
4042
+ hasError = true;
4043
+ reject(new Error('Async loader returned non-string source for "' + resolvedPath + '"'));
4044
+ return;
4045
+ }
4046
+ memMap[resolvedPath] = src;
4047
+ var targets;
4048
+ try {
4049
+ targets = exports.scan(src, scanOpts);
4050
+ } catch (e) {
4051
+ hasError = true;
4052
+ reject(e);
4053
+ return;
4054
+ }
4055
+ var i, resolvedChild;
4056
+ for (i = 0; i < targets.length; i += 1) {
4057
+ try {
4058
+ resolvedChild = loader.resolve(targets[i].path, resolvedPath);
4059
+ } catch (e) {
4060
+ hasError = true;
4061
+ reject(e);
4062
+ return;
4063
+ }
4064
+ enqueue(resolvedChild);
4065
+ }
4066
+ inFlight -= 1;
4067
+ drain();
4068
+ });
4069
+ }
4070
+ enqueue(entryPath);
4071
+ drain();
4072
+ });
4073
+ };
4074
+ exports.makeMemoryWrapper = function(userLoader, memMap) {
4075
+ return {
4076
+ resolve: function(to, from) {
4077
+ return userLoader.resolve(to, from);
4078
+ },
4079
+ load: function(id, cb) {
4080
+ var src = memMap[id];
4081
+ if (typeof src !== "string") {
4082
+ var err = new Error('Pre-walked map missing path: "' + id + '"');
4083
+ if (cb) {
4084
+ cb(err);
4085
+ return;
4086
+ }
4087
+ throw err;
4088
+ }
4089
+ if (cb) {
4090
+ cb(null, src);
4091
+ return;
4092
+ }
4093
+ return src;
4094
+ }
4095
+ };
4096
+ };
4097
+ }
4098
+ });
4099
+
3792
4100
  // packages/swig-core/lib/cache.js
3793
4101
  var require_cache = __commonJS({
3794
4102
  "packages/swig-core/lib/cache.js"(exports) {
@@ -3824,6 +4132,8 @@
3824
4132
  var utils = require_utils();
3825
4133
  var backend = require_backend();
3826
4134
  var cache = require_cache();
4135
+ var AsyncFunction = Object.getPrototypeOf(async function() {
4136
+ }).constructor;
3827
4137
  function efn() {
3828
4138
  return "";
3829
4139
  }
@@ -3874,14 +4184,12 @@
3874
4184
  return parents;
3875
4185
  };
3876
4186
  exports.buildTemplateFunction = function(tokens, parents, options) {
3877
- return new Function(
3878
- "_swig",
3879
- "_ctx",
3880
- "_filters",
3881
- "_utils",
3882
- "_fn",
3883
- ' var _ext = _swig.extensions,\n _output = "";\n' + backend.compile(tokens, parents, options) + "\n return _output;\n"
3884
- );
4187
+ if (options && options.codegenMode === "async") {
4188
+ var asyncBody = ' var _ext = _swig.extensions,\n _output = "",\n _exports = {};\n' + backend.compile(tokens, parents, options) + "\n return { output: _output, exports: _exports };\n";
4189
+ return new AsyncFunction("_swig", "_ctx", "_filters", "_utils", "_fn", "_blocks", asyncBody);
4190
+ }
4191
+ var body = ' var _ext = _swig.extensions,\n _output = "";\n' + backend.compile(tokens, parents, options) + "\n return _output;\n";
4192
+ return new Function("_swig", "_ctx", "_filters", "_utils", "_fn", body);
3885
4193
  };
3886
4194
  exports.install = function(self, frontend) {
3887
4195
  var parser = frontend.parser, tags = utils.extend({}, frontend.tags), filters = utils.extend({}, frontend.filters), validateOptions = frontend.validateOptions, onCompileError = frontend.onCompileError;
@@ -3979,7 +4287,7 @@
3979
4287
  context = getLocals(options);
3980
4288
  contextLength = utils.keys(context).length;
3981
4289
  pre = self.precompile(source, options);
3982
- function compiled(locals) {
4290
+ function compiled(locals, blocks) {
3983
4291
  var lcls;
3984
4292
  if (locals && contextLength) {
3985
4293
  lcls = utils.extend({}, context, locals);
@@ -3990,7 +4298,7 @@
3990
4298
  } else {
3991
4299
  lcls = {};
3992
4300
  }
3993
- return pre.tpl(self, lcls, filters, utils, efn);
4301
+ return pre.tpl(self, lcls, filters, utils, efn, blocks);
3994
4302
  }
3995
4303
  utils.extend(compiled, pre.tokens);
3996
4304
  if (key) {
@@ -4035,6 +4343,52 @@
4035
4343
  src = self.options.loader.load(pathname);
4036
4344
  return self.compile(src, options);
4037
4345
  };
4346
+ self.getTemplate = function(pathname, options) {
4347
+ options = options || {};
4348
+ var resolved;
4349
+ try {
4350
+ resolved = self.options.loader.resolve(pathname, options.resolveFrom);
4351
+ } catch (e) {
4352
+ return Promise.reject(e);
4353
+ }
4354
+ var compileOpts = utils.extend({}, options, {
4355
+ filename: options.filename || resolved,
4356
+ codegenMode: "async",
4357
+ cache: false
4358
+ });
4359
+ return new Promise(function(resolve, reject) {
4360
+ function onLoaded(err, src2) {
4361
+ if (err) {
4362
+ reject(err);
4363
+ return;
4364
+ }
4365
+ var compiled;
4366
+ try {
4367
+ compiled = self.compile(src2, compileOpts);
4368
+ } catch (err2) {
4369
+ reject(err2);
4370
+ return;
4371
+ }
4372
+ resolve(compiled);
4373
+ }
4374
+ if (self.options.loader.load.length >= 2) {
4375
+ try {
4376
+ self.options.loader.load(resolved, onLoaded);
4377
+ } catch (e) {
4378
+ onLoaded(e);
4379
+ }
4380
+ } else {
4381
+ var src;
4382
+ try {
4383
+ src = self.options.loader.load(resolved);
4384
+ } catch (e) {
4385
+ onLoaded(e);
4386
+ return;
4387
+ }
4388
+ onLoaded(null, src);
4389
+ }
4390
+ });
4391
+ };
4038
4392
  self.render = function(source, options) {
4039
4393
  return self.compile(source, options)();
4040
4394
  };
@@ -4078,8 +4432,9 @@
4078
4432
  var parser = require_parser();
4079
4433
  var dateformatter = require_dateformatter2();
4080
4434
  var loaders = require_loaders2();
4435
+ var preWalker = require_pre_walker();
4081
4436
  var engine = require_engine();
4082
- exports.version = "2.0.1";
4437
+ exports.version = "2.1.0";
4083
4438
  var defaultOptions = {
4084
4439
  autoescape: true,
4085
4440
  varControls: ["{{", "}}"],
@@ -4182,6 +4537,94 @@
4182
4537
  utils.throwError(err, null, options.filename);
4183
4538
  }
4184
4539
  });
4540
+ var self = this;
4541
+ function buildScanOpts() {
4542
+ return {
4543
+ varControls: self.options.varControls,
4544
+ tagControls: self.options.tagControls,
4545
+ cmtControls: self.options.cmtControls,
4546
+ rawTag: "raw",
4547
+ keywords: ["extends", "include", "import"]
4548
+ };
4549
+ }
4550
+ this.renderFileAsync = function(pathName, locals, cb) {
4551
+ if (typeof locals === "function") {
4552
+ cb = locals;
4553
+ locals = void 0;
4554
+ }
4555
+ var loader = self.options.loader;
4556
+ var entry;
4557
+ try {
4558
+ entry = loader.resolve(pathName);
4559
+ } catch (e) {
4560
+ cb(e);
4561
+ return;
4562
+ }
4563
+ preWalker.walk(entry, loader, buildScanOpts()).then(function(memMap) {
4564
+ var memWrapper = preWalker.makeMemoryWrapper(loader, memMap);
4565
+ var origLoader = self.options.loader;
4566
+ self.options.loader = memWrapper;
4567
+ var output, error;
4568
+ try {
4569
+ output = self.renderFile(entry, locals);
4570
+ } catch (e) {
4571
+ error = e;
4572
+ }
4573
+ self.options.loader = origLoader;
4574
+ if (error) {
4575
+ cb(error);
4576
+ return;
4577
+ }
4578
+ cb(null, output);
4579
+ }, function(err) {
4580
+ cb(err);
4581
+ });
4582
+ };
4583
+ this.compileFileAsync = function(pathName, options, cb) {
4584
+ if (typeof options === "function") {
4585
+ cb = options;
4586
+ options = {};
4587
+ }
4588
+ var loader = self.options.loader;
4589
+ var entry;
4590
+ try {
4591
+ entry = loader.resolve(pathName);
4592
+ } catch (e) {
4593
+ cb(e);
4594
+ return;
4595
+ }
4596
+ preWalker.walk(entry, loader, buildScanOpts()).then(function(memMap) {
4597
+ var memWrapper = preWalker.makeMemoryWrapper(loader, memMap);
4598
+ var origLoader = self.options.loader;
4599
+ self.options.loader = memWrapper;
4600
+ var compiled, error;
4601
+ try {
4602
+ compiled = self.compileFile(entry, options);
4603
+ } catch (e) {
4604
+ error = e;
4605
+ }
4606
+ self.options.loader = origLoader;
4607
+ if (error) {
4608
+ cb(error);
4609
+ return;
4610
+ }
4611
+ var wrapped = function(locals) {
4612
+ var origInner = self.options.loader;
4613
+ self.options.loader = memWrapper;
4614
+ try {
4615
+ var output = compiled(locals);
4616
+ self.options.loader = origInner;
4617
+ return output;
4618
+ } catch (e) {
4619
+ self.options.loader = origInner;
4620
+ throw e;
4621
+ }
4622
+ };
4623
+ cb(null, wrapped);
4624
+ }, function(err) {
4625
+ cb(err);
4626
+ });
4627
+ };
4185
4628
  };
4186
4629
  defaultInstance = new exports.Swig();
4187
4630
  exports.setFilter = defaultInstance.setFilter;
@@ -4191,8 +4634,10 @@
4191
4634
  exports.precompile = defaultInstance.precompile;
4192
4635
  exports.compile = defaultInstance.compile;
4193
4636
  exports.compileFile = defaultInstance.compileFile;
4637
+ exports.compileFileAsync = defaultInstance.compileFileAsync;
4194
4638
  exports.render = defaultInstance.render;
4195
4639
  exports.renderFile = defaultInstance.renderFile;
4640
+ exports.renderFileAsync = defaultInstance.renderFileAsync;
4196
4641
  exports.run = defaultInstance.run;
4197
4642
  exports.invalidateCache = defaultInstance.invalidateCache;
4198
4643
  exports.loaders = loaders;
@@ -4273,10 +4718,13 @@
4273
4718
  * compiled VarRef body relies on. @private
4274
4719
  */
4275
4720
  /*!
4276
- * Replica of `TokenParser.prototype.checkMatch`. Kept as a local private
4277
- * helper rather than imported from tokenparser.js because (a) it is a
4278
- * pure function of its argument and (b) the backend must not acquire a
4279
- * runtime dependency on the TokenParser module (which is a specific
4721
+ * Build the dot-path emit. `(checkDot_ctx ? _ctx.<path> : (checkDot_closure
4722
+ * ? <path> : ""))` checks the `_ctx.<path>` walk first, falls back to a
4723
+ * bare-closure walk (covers macro params, host-globals like `Math`), and
4724
+ * coerces a missing path to `""` for safe interpolation. Kept as a local
4725
+ * private helper rather than imported from tokenparser.js because (a) it
4726
+ * is a pure function of its argument and (b) the backend must not acquire
4727
+ * a runtime dependency on the TokenParser module (which is a specific
4280
4728
  * frontend concern, not a shared-backend one). @private
4281
4729
  */
4282
4730
  /*!
@@ -4316,6 +4764,21 @@
4316
4764
  * Loop over the source, split via the tag/var/comment regular expression splitter.
4317
4765
  * Send each chunk to the appropriate parser.
4318
4766
  */
4767
+ /*!
4768
+ * Makes a string safe for a regular expression. Mirrors lib/parser.js.
4769
+ * @private
4770
+ */
4771
+ /*!
4772
+ * Build the splitter regex from the controls trio. Mirrors the regex that
4773
+ * parser.parse() builds at parse-time so the pre-walker chunks the same
4774
+ * way the real parser would.
4775
+ * @private
4776
+ */
4777
+ /*!
4778
+ * Strip tag controls and optional whitespace-control markers from a tag
4779
+ * chunk, returning the trimmed tag body (e.g. `extends "x.html"`).
4780
+ * @private
4781
+ */
4319
4782
  /*!
4320
4783
  * Export methods publicly
4321
4784
  */