@messagevisor/catalog 0.7.0 → 0.9.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/lib/node/index.js CHANGED
@@ -89,7 +89,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
89
89
  return to.concat(ar || Array.prototype.slice.call(from));
90
90
  };
91
91
  Object.defineProperty(exports, "__esModule", { value: true });
92
- exports.CATALOG_HISTORY_PAGE_SIZE = exports.CATALOG_SCHEMA_VERSION = void 0;
92
+ exports.__catalogDevInternals = exports.CATALOG_HISTORY_PAGE_SIZE = exports.CATALOG_SCHEMA_VERSION = void 0;
93
93
  exports.exportCatalog = exportCatalog;
94
94
  exports.serveCatalog = serveCatalog;
95
95
  exports.createCatalogApi = createCatalogApi;
@@ -376,7 +376,7 @@ function resolveLocaleChain(localeKey, locales, field) {
376
376
  }
377
377
  function getLocaleFormatSource(localeKey, locales, formatPath) {
378
378
  var _a, _b;
379
- var pathSegments = formatPath.split(".");
379
+ var pathSegments = getFormatStylePathSegments(formatPath);
380
380
  if (typeof getPathValue((_a = locales[localeKey]) === null || _a === void 0 ? void 0 : _a.formats, pathSegments) !== "undefined") {
381
381
  return { source: "direct" };
382
382
  }
@@ -390,12 +390,17 @@ function getLocaleFormatSource(localeKey, locales, formatPath) {
390
390
  }
391
391
  return { source: "missing" };
392
392
  }
393
+ function getFormatStylePathSegments(formatPath) {
394
+ var pathSegments = formatPath.split(".").filter(Boolean);
395
+ return pathSegments.length > 2 ? pathSegments.slice(0, 2) : pathSegments;
396
+ }
393
397
  function getFormatRows(runtime, localeKey, locales, target) {
394
398
  var computedFormats = runtime.resolveFormats(localeKey, locales, target) || {};
395
399
  var rows = flattenObjectRows(computedFormats).map(function (row) {
396
400
  var _a;
397
401
  if (target &&
398
- typeof getPathValue((_a = target.formats) === null || _a === void 0 ? void 0 : _a[localeKey], row.path.split(".")) !== "undefined") {
402
+ typeof getPathValue((_a = target.formats) === null || _a === void 0 ? void 0 : _a[localeKey], getFormatStylePathSegments(row.path)) !==
403
+ "undefined") {
399
404
  return __assign(__assign({}, row), { source: "target", from: "target" });
400
405
  }
401
406
  return __assign(__assign({}, row), getLocaleFormatSource(localeKey, locales, row.path));
@@ -1503,12 +1508,404 @@ function copyCatalogAssets(outputDirectoryPath) {
1503
1508
  });
1504
1509
  });
1505
1510
  }
1511
+ function createCatalogDevSession(rootDirectoryPath_1, projectConfig_1) {
1512
+ return __awaiter(this, arguments, void 0, function (rootDirectoryPath, projectConfig, options) {
1513
+ var outputDirectoryPath;
1514
+ var _a;
1515
+ if (options === void 0) { options = {}; }
1516
+ return __generator(this, function (_b) {
1517
+ switch (_b.label) {
1518
+ case 0:
1519
+ outputDirectoryPath = options.outDir
1520
+ ? path.resolve(rootDirectoryPath, options.outDir)
1521
+ : projectConfig.catalogDirectoryPath;
1522
+ _a = {
1523
+ outputDirectoryPath: outputDirectoryPath,
1524
+ devEditors: options.devEditors || detectDevEditors()
1525
+ };
1526
+ return [4 /*yield*/, getGitHistoryIndex(rootDirectoryPath, projectConfig)];
1527
+ case 1: return [2 /*return*/, (_a.historyIndex = _b.sent(),
1528
+ _a.links = getRepoLinks(rootDirectoryPath),
1529
+ _a.repositoryRootDirectoryPath = getRepositoryRootDirectoryPath(rootDirectoryPath),
1530
+ _a.repositorySourceRootDirectoryPath = getRepositorySourceRootDirectoryPath(rootDirectoryPath),
1531
+ _a)];
1532
+ }
1533
+ });
1534
+ });
1535
+ }
1536
+ function readJsonFile(filePath) {
1537
+ return __awaiter(this, void 0, void 0, function () {
1538
+ var _a, _b, _error_2;
1539
+ return __generator(this, function (_c) {
1540
+ switch (_c.label) {
1541
+ case 0:
1542
+ _c.trys.push([0, 2, , 3]);
1543
+ _b = (_a = JSON).parse;
1544
+ return [4 /*yield*/, fs.promises.readFile(filePath, "utf8")];
1545
+ case 1: return [2 /*return*/, _b.apply(_a, [_c.sent()])];
1546
+ case 2:
1547
+ _error_2 = _c.sent();
1548
+ return [2 /*return*/, undefined];
1549
+ case 3: return [2 /*return*/];
1550
+ }
1551
+ });
1552
+ });
1553
+ }
1554
+ function getOutputRelativeDirectory(projectConfig, set) {
1555
+ return projectConfig.sets ? path.join("sets", set || "") : "root";
1556
+ }
1557
+ function getDataOutputDirectoryPath(session, projectConfig, set) {
1558
+ return path.join(session.outputDirectoryPath, "data", getOutputRelativeDirectory(projectConfig, set));
1559
+ }
1560
+ function getEntityKeyFromChangedPath(rootDirectoryPath, projectConfig, changedPath) {
1561
+ var relativePath = path.relative(rootDirectoryPath, changedPath);
1562
+ if (!relativePath || relativePath.startsWith("..") || path.isAbsolute(relativePath)) {
1563
+ return undefined;
1564
+ }
1565
+ return getEntityInfoFromRelativePath(rootDirectoryPath, projectConfig, relativePath);
1566
+ }
1567
+ function getChangedPathSummary(rootDirectoryPath, changedPaths) {
1568
+ return changedPaths
1569
+ .slice(0, 3)
1570
+ .map(function (changedPath) { return formatCatalogPath(rootDirectoryPath, changedPath); })
1571
+ .join(", ");
1572
+ }
1573
+ function classifyCatalogDevChanges(rootDirectoryPath, projectConfig, changedPaths, options) {
1574
+ var reason = getChangedPathSummary(rootDirectoryPath, changedPaths) || "project changes";
1575
+ var infos = changedPaths.map(function (changedPath) {
1576
+ return getEntityKeyFromChangedPath(rootDirectoryPath, projectConfig, changedPath);
1577
+ });
1578
+ if (infos.length === 0 || infos.some(function (info) { return !info; })) {
1579
+ return { kind: "full", reason: reason };
1580
+ }
1581
+ var sets = new Set(infos.map(function (info) { return (info === null || info === void 0 ? void 0 : info.set) || ""; }));
1582
+ var types = new Set(infos.map(function (info) { return info === null || info === void 0 ? void 0 : info.type; }));
1583
+ if (sets.size > 1) {
1584
+ return { kind: "full", reason: reason };
1585
+ }
1586
+ var set = Array.from(sets)[0] || undefined;
1587
+ if (types.size === 1 &&
1588
+ types.has("message") &&
1589
+ !options.withTranslationSearch &&
1590
+ !options.withDuplicates) {
1591
+ return {
1592
+ kind: "message",
1593
+ reason: reason,
1594
+ set: set,
1595
+ messageKeys: sortStrings(infos.map(function (info) { return (info === null || info === void 0 ? void 0 : info.key) || ""; }).filter(Boolean)),
1596
+ };
1597
+ }
1598
+ if (projectConfig.sets &&
1599
+ set &&
1600
+ types.size > 0 &&
1601
+ !types.has("test") &&
1602
+ !options.withTranslationSearch &&
1603
+ !options.withDuplicates) {
1604
+ return { kind: "set", reason: reason, set: set };
1605
+ }
1606
+ return { kind: "full", reason: reason };
1607
+ }
1608
+ function writeCatalogManifest(writer, rootDirectoryPath, projectConfig, session, options) {
1609
+ return __awaiter(this, void 0, void 0, function () {
1610
+ var manifest;
1611
+ return __generator(this, function (_a) {
1612
+ switch (_a.label) {
1613
+ case 0:
1614
+ manifest = {
1615
+ schemaVersion: exports.CATALOG_SCHEMA_VERSION,
1616
+ generatedAt: new Date().toISOString(),
1617
+ router: options.browserRouter === false ? "hash" : "browser",
1618
+ sets: projectConfig.sets,
1619
+ setKeys: projectConfig.sets ? options.executions.map(function (execution) { return execution.set; }) : [],
1620
+ dev: { editors: session.devEditors },
1621
+ features: {
1622
+ translationSearch: options.withTranslationSearch,
1623
+ duplicates: options.withDuplicates,
1624
+ },
1625
+ links: session.links,
1626
+ paths: {
1627
+ projectHistory: "data/project/history/page-1.json",
1628
+ root: projectConfig.sets ? undefined : "data/root/index.json",
1629
+ sets: projectConfig.sets
1630
+ ? Object.fromEntries(options.executions.map(function (execution) { return [
1631
+ execution.set,
1632
+ "data/sets/".concat(encodeURIComponent(execution.set), "/index.json"),
1633
+ ]; }))
1634
+ : undefined,
1635
+ },
1636
+ counts: Object.fromEntries(Object.keys(options.setIndexes).map(function (key) { return [key, options.setIndexes[key].counts]; })),
1637
+ };
1638
+ return [4 /*yield*/, writer.write(path.join(session.outputDirectoryPath, "data", "manifest.json"), manifest)];
1639
+ case 1:
1640
+ _a.sent();
1641
+ return [2 /*return*/, manifest];
1642
+ }
1643
+ });
1644
+ });
1645
+ }
1646
+ function getMessageRelationshipFingerprint(message) {
1647
+ var attributes = new Set();
1648
+ var segments = new Set();
1649
+ for (var _i = 0, _a = message.overrides || []; _i < _a.length; _i++) {
1650
+ var override = _a[_i];
1651
+ collectAttributeKeysFromConditions(override.conditions, attributes);
1652
+ collectSegmentKeys(override.segments, segments);
1653
+ }
1654
+ return {
1655
+ attributes: sortStrings(Array.from(attributes)),
1656
+ segments: sortStrings(Array.from(segments)),
1657
+ };
1658
+ }
1659
+ function sameStringList(left, right) {
1660
+ if (left === void 0) { left = []; }
1661
+ if (right === void 0) { right = []; }
1662
+ if (left.length !== right.length) {
1663
+ return false;
1664
+ }
1665
+ return left.every(function (value, index) { return value === right[index]; });
1666
+ }
1667
+ function summarizeMessage(message, messageKey, historyIndex, set, targets) {
1668
+ var directLocales = Object.keys(message.translations || {});
1669
+ var overrideLocalesSet = new Set();
1670
+ for (var _i = 0, _a = message.overrides || []; _i < _a.length; _i++) {
1671
+ var override = _a[_i];
1672
+ for (var _b = 0, _c = Object.keys(override.translations || {}); _b < _c.length; _b++) {
1673
+ var localeKey = _c[_b];
1674
+ overrideLocalesSet.add(localeKey);
1675
+ }
1676
+ }
1677
+ var overrideLocales = sortStrings(Array.from(overrideLocalesSet));
1678
+ return getEntitySummary(message, "message", messageKey, historyIndex, set, __assign(__assign({ targets: targets }, (directLocales.length > 0 ? { locales: sortStrings(directLocales) } : {})), (overrideLocales.length > 0 ? { overrideLocales: overrideLocales } : {})));
1679
+ }
1680
+ function tryRebuildCatalogMessage(runtime, rootDirectoryPath, rootProjectConfig, projectConfig, datasource, session, request) {
1681
+ return __awaiter(this, void 0, void 0, function () {
1682
+ var dataDirectoryPath, indexPath, index, _a, localeKeys, messageKeys, targetKeys, messageKeySet, _b, locales, targets, localeDirections, targetMessages, writer, _loop_1, _i, _c, messageKey, state_1;
1683
+ return __generator(this, function (_d) {
1684
+ switch (_d.label) {
1685
+ case 0:
1686
+ if (request.kind !== "message" || !request.messageKeys || request.messageKeys.length === 0) {
1687
+ return [2 /*return*/, false];
1688
+ }
1689
+ dataDirectoryPath = getDataOutputDirectoryPath(session, rootProjectConfig, request.set);
1690
+ indexPath = path.join(dataDirectoryPath, "index.json");
1691
+ return [4 /*yield*/, readJsonFile(indexPath)];
1692
+ case 1:
1693
+ index = _d.sent();
1694
+ if (!index) {
1695
+ return [2 /*return*/, false];
1696
+ }
1697
+ return [4 /*yield*/, Promise.all([
1698
+ datasource.listLocales(),
1699
+ datasource.listMessages(),
1700
+ datasource.listTargets(),
1701
+ ])];
1702
+ case 2:
1703
+ _a = (_d.sent()), localeKeys = _a[0], messageKeys = _a[1], targetKeys = _a[2];
1704
+ messageKeySet = new Set(messageKeys);
1705
+ if (request.messageKeys.some(function (messageKey) { return !messageKeySet.has(messageKey); })) {
1706
+ return [2 /*return*/, false];
1707
+ }
1708
+ return [4 /*yield*/, Promise.all([
1709
+ readAll(localeKeys, function (key) { return datasource.readLocale(key); }),
1710
+ readAll(targetKeys, function (key) { return datasource.readTarget(key); }),
1711
+ ])];
1712
+ case 3:
1713
+ _b = _d.sent(), locales = _b[0], targets = _b[1];
1714
+ localeDirections = getLocaleDirections(locales);
1715
+ targetMessages = Object.fromEntries(targetKeys.map(function (targetKey) { return [
1716
+ targetKey,
1717
+ getTargetMessageKeys(targets[targetKey], messageKeys),
1718
+ ]; }));
1719
+ writer = new CatalogJsonWriter();
1720
+ _loop_1 = function (messageKey) {
1721
+ var oldDetailPath, oldDetail, message, messageTargets, oldRelationshipFingerprint, nextRelationshipFingerprint, examples, overrides, sourceFileInfo, detail, nextSummary, existingSummaryIndex;
1722
+ return __generator(this, function (_e) {
1723
+ switch (_e.label) {
1724
+ case 0:
1725
+ oldDetailPath = path.join(dataDirectoryPath, "entities", "message", "".concat(encodeKey(messageKey), ".json"));
1726
+ return [4 /*yield*/, readJsonFile(oldDetailPath)];
1727
+ case 1:
1728
+ oldDetail = _e.sent();
1729
+ if (!oldDetail) {
1730
+ return [2 /*return*/, { value: false }];
1731
+ }
1732
+ return [4 /*yield*/, datasource.readMessage(messageKey)];
1733
+ case 2:
1734
+ message = _e.sent();
1735
+ messageTargets = sortStrings(targetKeys.filter(function (targetKey) { return targetMessages[targetKey].includes(messageKey); }));
1736
+ if (!sameStringList(sortStrings(oldDetail.targets || []), messageTargets)) {
1737
+ return [2 /*return*/, { value: false }];
1738
+ }
1739
+ oldRelationshipFingerprint = getMessageRelationshipFingerprint(oldDetail.entity || {});
1740
+ nextRelationshipFingerprint = getMessageRelationshipFingerprint(message);
1741
+ if (!sameStringList(oldRelationshipFingerprint.attributes, nextRelationshipFingerprint.attributes) ||
1742
+ !sameStringList(oldRelationshipFingerprint.segments, nextRelationshipFingerprint.segments)) {
1743
+ return [2 /*return*/, { value: false }];
1744
+ }
1745
+ return [4 /*yield*/, runtime.resolveExamples(projectConfig, datasource, {
1746
+ set: request.set,
1747
+ message: messageKey,
1748
+ onlyMessages: true,
1749
+ })];
1750
+ case 3:
1751
+ examples = _e.sent();
1752
+ overrides = (message.overrides || []).map(function (override) {
1753
+ var attributes = new Set();
1754
+ var overrideSegments = new Set();
1755
+ collectAttributeKeysFromConditions(override.conditions, attributes);
1756
+ collectSegmentKeys(override.segments, overrideSegments);
1757
+ return __assign(__assign({}, override), { usedAttributes: sortStrings(Array.from(attributes)), usedSegments: sortStrings(Array.from(overrideSegments)) });
1758
+ });
1759
+ sourceFileInfo = getSourceFileInfo(session.repositorySourceRootDirectoryPath, rootDirectoryPath, projectConfig, "message", messageKey, { resolveAbsolutePath: session.devEditors.length > 0 });
1760
+ detail = {
1761
+ type: "message",
1762
+ key: messageKey,
1763
+ entity: __assign(__assign({}, message), { overrides: overrides }),
1764
+ sourcePath: sourceFileInfo.sourcePath,
1765
+ editLinks: getEditorLinks(session.devEditors, sourceFileInfo),
1766
+ targets: messageTargets,
1767
+ localeKeys: localeKeys,
1768
+ localeDirections: localeDirections,
1769
+ translations: localeKeys.map(function (localeKey) {
1770
+ return resolveTranslationRow(message.translations, localeKey, locales);
1771
+ }),
1772
+ evaluatedExamples: examples.messages,
1773
+ overrideTranslations: overrides.map(function (override) { return ({
1774
+ key: override.key,
1775
+ rows: localeKeys.map(function (localeKey) {
1776
+ return resolveTranslationRow(override.translations, localeKey, locales);
1777
+ }),
1778
+ }); }),
1779
+ lastModified: getLastModified(session.historyIndex, "message", messageKey, request.set),
1780
+ };
1781
+ return [4 /*yield*/, writer.write(oldDetailPath, detail)];
1782
+ case 4:
1783
+ _e.sent();
1784
+ return [4 /*yield*/, writeHistoryPages(writer, path.join(dataDirectoryPath, "history", "message", encodeKey(messageKey)), getHistoryForEntity(session.historyIndex, "message", messageKey, request.set), { skipEmpty: true })];
1785
+ case 5:
1786
+ _e.sent();
1787
+ nextSummary = summarizeMessage(message, messageKey, session.historyIndex, request.set, messageTargets);
1788
+ existingSummaryIndex = index.entities.message.findIndex(function (entry) { return entry.key === messageKey; });
1789
+ if (existingSummaryIndex === -1) {
1790
+ index.entities.message.push(nextSummary);
1791
+ }
1792
+ else {
1793
+ index.entities.message[existingSummaryIndex] = nextSummary;
1794
+ }
1795
+ return [2 /*return*/];
1796
+ }
1797
+ });
1798
+ };
1799
+ _i = 0, _c = request.messageKeys;
1800
+ _d.label = 4;
1801
+ case 4:
1802
+ if (!(_i < _c.length)) return [3 /*break*/, 7];
1803
+ messageKey = _c[_i];
1804
+ return [5 /*yield**/, _loop_1(messageKey)];
1805
+ case 5:
1806
+ state_1 = _d.sent();
1807
+ if (typeof state_1 === "object")
1808
+ return [2 /*return*/, state_1.value];
1809
+ _d.label = 6;
1810
+ case 6:
1811
+ _i++;
1812
+ return [3 /*break*/, 4];
1813
+ case 7:
1814
+ index.entities.message.sort(function (left, right) { return left.key.localeCompare(right.key); });
1815
+ index.counts.message = messageKeys.length;
1816
+ return [4 /*yield*/, writer.write(indexPath, index)];
1817
+ case 8:
1818
+ _d.sent();
1819
+ return [2 /*return*/, true];
1820
+ }
1821
+ });
1822
+ });
1823
+ }
1824
+ function rebuildCatalogSetForDev(runtime, rootDirectoryPath, projectConfig, datasource, session, options) {
1825
+ return __awaiter(this, void 0, void 0, function () {
1826
+ var writer, progress, executions, setIndexes, existingIndexes, _i, existingIndexes_1, _a, key, index, execution, outputRelativeDirectory, context, _b, _c;
1827
+ var _this = this;
1828
+ return __generator(this, function (_d) {
1829
+ switch (_d.label) {
1830
+ case 0:
1831
+ writer = new CatalogJsonWriter();
1832
+ progress = new CatalogProgressReporter(rootDirectoryPath, session.outputDirectoryPath);
1833
+ return [4 /*yield*/, runtime.getProjectSetExecutions(projectConfig, datasource)];
1834
+ case 1:
1835
+ executions = _d.sent();
1836
+ setIndexes = {};
1837
+ return [4 /*yield*/, Promise.all(executions.map(function (execution) { return __awaiter(_this, void 0, void 0, function () {
1838
+ var indexPath, _a;
1839
+ return __generator(this, function (_b) {
1840
+ switch (_b.label) {
1841
+ case 0:
1842
+ indexPath = path.join(session.outputDirectoryPath, "data", getOutputRelativeDirectory(projectConfig, execution.set), "index.json");
1843
+ _a = [execution.set || "root"];
1844
+ return [4 /*yield*/, readJsonFile(indexPath)];
1845
+ case 1: return [2 /*return*/, _a.concat([_b.sent()])];
1846
+ }
1847
+ });
1848
+ }); }))];
1849
+ case 2:
1850
+ existingIndexes = _d.sent();
1851
+ for (_i = 0, existingIndexes_1 = existingIndexes; _i < existingIndexes_1.length; _i++) {
1852
+ _a = existingIndexes_1[_i], key = _a[0], index = _a[1];
1853
+ if (index) {
1854
+ setIndexes[key] = index;
1855
+ }
1856
+ }
1857
+ execution = executions.find(function (item) { return (item.set || undefined) === options.set; });
1858
+ if (!execution) {
1859
+ return [2 /*return*/, false];
1860
+ }
1861
+ outputRelativeDirectory = getOutputRelativeDirectory(projectConfig, execution.set);
1862
+ return [4 /*yield*/, fs.promises.rm(path.join(session.outputDirectoryPath, "data", outputRelativeDirectory), {
1863
+ recursive: true,
1864
+ force: true,
1865
+ })];
1866
+ case 3:
1867
+ _d.sent();
1868
+ context = {
1869
+ rootDirectoryPath: rootDirectoryPath,
1870
+ repositoryRootDirectoryPath: session.repositoryRootDirectoryPath,
1871
+ repositorySourceRootDirectoryPath: session.repositorySourceRootDirectoryPath,
1872
+ outputDirectoryPath: session.outputDirectoryPath,
1873
+ dataDirectoryPath: path.join(session.outputDirectoryPath, "data"),
1874
+ historyIndex: session.historyIndex,
1875
+ runtime: runtime,
1876
+ devEditors: session.devEditors,
1877
+ duplicateResultsBySet: {},
1878
+ withTranslationSearch: options.withTranslationSearch,
1879
+ withDuplicates: options.withDuplicates,
1880
+ progress: progress,
1881
+ writer: writer,
1882
+ };
1883
+ _b = setIndexes;
1884
+ _c = execution.set || "root";
1885
+ return [4 /*yield*/, buildSetCatalog(context, execution.set, execution.projectConfig, execution.datasource, outputRelativeDirectory)];
1886
+ case 4:
1887
+ _b[_c] = _d.sent();
1888
+ return [4 /*yield*/, writeCatalogManifest(writer, rootDirectoryPath, projectConfig, session, {
1889
+ browserRouter: options.browserRouter,
1890
+ withTranslationSearch: options.withTranslationSearch,
1891
+ withDuplicates: options.withDuplicates,
1892
+ setIndexes: setIndexes,
1893
+ executions: executions,
1894
+ })];
1895
+ case 5:
1896
+ _d.sent();
1897
+ return [2 /*return*/, true];
1898
+ }
1899
+ });
1900
+ });
1901
+ }
1506
1902
  function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasource_1) {
1507
1903
  return __awaiter(this, arguments, void 0, function (runtime, rootDirectoryPath, projectConfig, datasource, options) {
1508
- var outputDirectoryPath, dataDirectoryPath, withTranslationSearch, withDuplicates, progress, writer, stepStartedAt, devEditors, historyIndex, links, duplicateResultsBySet, _a, _b, context, executions, setIndexes, _i, executions_1, execution, outputRelativeDirectory, _c, _d, manifest;
1904
+ var outputDirectoryPath, dataDirectoryPath, withTranslationSearch, withDuplicates, progress, writer, stepStartedAt, devEditors, historyIndex, _a, links, duplicateResultsBySet, _b, _c, context, executions, setIndexes, _i, executions_1, execution, outputRelativeDirectory, _d, _e, manifest;
1905
+ var _f, _g, _h, _j, _k;
1509
1906
  if (options === void 0) { options = {}; }
1510
- return __generator(this, function (_e) {
1511
- switch (_e.label) {
1907
+ return __generator(this, function (_l) {
1908
+ switch (_l.label) {
1512
1909
  case 0:
1513
1910
  outputDirectoryPath = options.outDir
1514
1911
  ? path.resolve(rootDirectoryPath, options.outDir)
@@ -1524,37 +1921,50 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1524
1921
  features: __spreadArray(__spreadArray([], (withTranslationSearch ? ["translation search"] : []), true), (withDuplicates ? ["duplicates"] : []), true),
1525
1922
  });
1526
1923
  stepStartedAt = progress.step("Preparing output directory");
1527
- return [4 /*yield*/, fs.promises.rm(outputDirectoryPath, { recursive: true, force: true })];
1924
+ if (!options.preserveAssets) return [3 /*break*/, 2];
1925
+ return [4 /*yield*/, fs.promises.rm(dataDirectoryPath, { recursive: true, force: true })];
1528
1926
  case 1:
1529
- _e.sent();
1530
- return [4 /*yield*/, fs.promises.mkdir(dataDirectoryPath, { recursive: true })];
1531
- case 2:
1532
- _e.sent();
1927
+ _l.sent();
1928
+ return [3 /*break*/, 4];
1929
+ case 2: return [4 /*yield*/, fs.promises.rm(outputDirectoryPath, { recursive: true, force: true })];
1930
+ case 3:
1931
+ _l.sent();
1932
+ _l.label = 4;
1933
+ case 4: return [4 /*yield*/, fs.promises.mkdir(dataDirectoryPath, { recursive: true })];
1934
+ case 5:
1935
+ _l.sent();
1533
1936
  progress.done(stepStartedAt);
1534
- if (!(options.copyAssets !== false)) return [3 /*break*/, 4];
1937
+ if (!(options.copyAssets !== false)) return [3 /*break*/, 7];
1535
1938
  stepStartedAt = progress.step("Copying Catalog UI assets");
1536
1939
  return [4 /*yield*/, copyCatalogAssets(outputDirectoryPath)];
1537
- case 3:
1538
- _e.sent();
1940
+ case 6:
1941
+ _l.sent();
1539
1942
  progress.done(stepStartedAt);
1540
- _e.label = 4;
1541
- case 4:
1542
- devEditors = options.dev ? options.devEditors || detectDevEditors() : [];
1943
+ _l.label = 7;
1944
+ case 7:
1945
+ devEditors = options.dev
1946
+ ? ((_f = options.devSession) === null || _f === void 0 ? void 0 : _f.devEditors) || options.devEditors || detectDevEditors()
1947
+ : [];
1543
1948
  stepStartedAt = progress.step("Reading Git history");
1949
+ _a = ((_g = options.devSession) === null || _g === void 0 ? void 0 : _g.historyIndex);
1950
+ if (_a) return [3 /*break*/, 9];
1544
1951
  return [4 /*yield*/, getGitHistoryIndex(rootDirectoryPath, projectConfig)];
1545
- case 5:
1546
- historyIndex = _e.sent();
1952
+ case 8:
1953
+ _a = (_l.sent());
1954
+ _l.label = 9;
1955
+ case 9:
1956
+ historyIndex = _a;
1547
1957
  progress.done(stepStartedAt, "(".concat(pluralize(historyIndex.entries.length, "commit"), ")"));
1548
1958
  stepStartedAt = progress.step("Resolving repository links");
1549
- links = getRepoLinks(rootDirectoryPath);
1959
+ links = ((_h = options.devSession) === null || _h === void 0 ? void 0 : _h.links) || getRepoLinks(rootDirectoryPath);
1550
1960
  progress.done(stepStartedAt);
1551
1961
  duplicateResultsBySet = {};
1552
- if (!withDuplicates) return [3 /*break*/, 7];
1962
+ if (!withDuplicates) return [3 /*break*/, 11];
1553
1963
  stepStartedAt = progress.step("Scanning duplicate translations");
1554
- _b = (_a = Object).fromEntries;
1964
+ _c = (_b = Object).fromEntries;
1555
1965
  return [4 /*yield*/, runtime.findDuplicateTranslations(projectConfig, datasource)];
1556
- case 6:
1557
- duplicateResultsBySet = _b.apply(_a, [(_e.sent()).results.map(function (result) { return [
1966
+ case 10:
1967
+ duplicateResultsBySet = _c.apply(_b, [(_l.sent()).results.map(function (result) { return [
1558
1968
  getDuplicateSetKey(result.set),
1559
1969
  result,
1560
1970
  ]; })]);
@@ -1562,12 +1972,14 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1562
1972
  return total +
1563
1973
  result.locales.reduce(function (localeTotal, localeResult) { return localeTotal + localeResult.duplicateValues.length; }, 0);
1564
1974
  }, 0), "duplicate value"), ")"));
1565
- _e.label = 7;
1566
- case 7:
1975
+ _l.label = 11;
1976
+ case 11:
1567
1977
  context = {
1568
1978
  rootDirectoryPath: rootDirectoryPath,
1569
- repositoryRootDirectoryPath: getRepositoryRootDirectoryPath(rootDirectoryPath),
1570
- repositorySourceRootDirectoryPath: getRepositorySourceRootDirectoryPath(rootDirectoryPath),
1979
+ repositoryRootDirectoryPath: ((_j = options.devSession) === null || _j === void 0 ? void 0 : _j.repositoryRootDirectoryPath) ||
1980
+ getRepositoryRootDirectoryPath(rootDirectoryPath),
1981
+ repositorySourceRootDirectoryPath: ((_k = options.devSession) === null || _k === void 0 ? void 0 : _k.repositorySourceRootDirectoryPath) ||
1982
+ getRepositorySourceRootDirectoryPath(rootDirectoryPath),
1571
1983
  outputDirectoryPath: outputDirectoryPath,
1572
1984
  dataDirectoryPath: dataDirectoryPath,
1573
1985
  historyIndex: historyIndex,
@@ -1581,33 +1993,33 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1581
1993
  };
1582
1994
  stepStartedAt = progress.step("Discovering project sets");
1583
1995
  return [4 /*yield*/, runtime.getProjectSetExecutions(projectConfig, datasource)];
1584
- case 8:
1585
- executions = _e.sent();
1996
+ case 12:
1997
+ executions = _l.sent();
1586
1998
  progress.done(stepStartedAt, projectConfig.sets
1587
1999
  ? "(".concat(executions.map(function (execution) { return execution.set; }).join(", ") || "none", ")")
1588
2000
  : "(root)");
1589
2001
  setIndexes = {};
1590
2002
  stepStartedAt = progress.step("Writing project history");
1591
2003
  return [4 /*yield*/, writeHistoryPages(writer, path.join(dataDirectoryPath, "project", "history"), historyIndex.entries)];
1592
- case 9:
1593
- _e.sent();
2004
+ case 13:
2005
+ _l.sent();
1594
2006
  progress.done(stepStartedAt, "(".concat(pluralize(historyIndex.entries.length, "entry", "entries"), ")"));
1595
2007
  _i = 0, executions_1 = executions;
1596
- _e.label = 10;
1597
- case 10:
1598
- if (!(_i < executions_1.length)) return [3 /*break*/, 13];
2008
+ _l.label = 14;
2009
+ case 14:
2010
+ if (!(_i < executions_1.length)) return [3 /*break*/, 17];
1599
2011
  execution = executions_1[_i];
1600
2012
  outputRelativeDirectory = projectConfig.sets ? path.join("sets", execution.set) : "root";
1601
- _c = setIndexes;
1602
- _d = execution.set || "root";
2013
+ _d = setIndexes;
2014
+ _e = execution.set || "root";
1603
2015
  return [4 /*yield*/, buildSetCatalog(context, execution.set, execution.projectConfig, execution.datasource, outputRelativeDirectory)];
1604
- case 11:
1605
- _c[_d] = _e.sent();
1606
- _e.label = 12;
1607
- case 12:
2016
+ case 15:
2017
+ _d[_e] = _l.sent();
2018
+ _l.label = 16;
2019
+ case 16:
1608
2020
  _i++;
1609
- return [3 /*break*/, 10];
1610
- case 13:
2021
+ return [3 /*break*/, 14];
2022
+ case 17:
1611
2023
  stepStartedAt = progress.step("Writing manifest");
1612
2024
  manifest = {
1613
2025
  schemaVersion: exports.CATALOG_SCHEMA_VERSION,
@@ -1634,8 +2046,8 @@ function exportCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasour
1634
2046
  counts: Object.fromEntries(Object.keys(setIndexes).map(function (key) { return [key, setIndexes[key].counts]; })),
1635
2047
  };
1636
2048
  return [4 /*yield*/, writer.write(path.join(dataDirectoryPath, "manifest.json"), manifest)];
1637
- case 14:
1638
- _e.sent();
2049
+ case 18:
2050
+ _l.sent();
1639
2051
  progress.done(stepStartedAt);
1640
2052
  progress.complete();
1641
2053
  return [2 /*return*/, {
@@ -1686,7 +2098,17 @@ function injectCatalogLiveReloadClient(html) {
1686
2098
  }
1687
2099
  return "".concat(html).concat(script);
1688
2100
  }
1689
- function createProjectWatcher(rootDirectoryPath, ignoredDirectoryPaths, onChange) {
2101
+ function getCatalogInputWatchPaths(rootDirectoryPath, projectConfig) {
2102
+ var paths = [path.join(rootDirectoryPath, "messagevisor.config.js")];
2103
+ if (projectConfig.sets) {
2104
+ paths.push(projectConfig.setsDirectoryPath);
2105
+ return paths;
2106
+ }
2107
+ paths.push(projectConfig.localesDirectoryPath, projectConfig.messagesDirectoryPath, projectConfig.attributesDirectoryPath, projectConfig.segmentsDirectoryPath, projectConfig.targetsDirectoryPath, projectConfig.testsDirectoryPath);
2108
+ return paths.filter(function (entry) { return typeof entry === "string" && entry.length > 0; });
2109
+ }
2110
+ function createCatalogInputWatcher(rootDirectoryPath, projectConfig, ignoredDirectoryPaths, onChange) {
2111
+ var watchPaths = getCatalogInputWatchPaths(rootDirectoryPath, projectConfig);
1690
2112
  function shouldIgnore(targetPath) {
1691
2113
  var resolvedTargetPath = path.resolve(targetPath);
1692
2114
  return ignoredDirectoryPaths.some(function (ignoredDirectoryPath) {
@@ -1695,6 +2117,17 @@ function createProjectWatcher(rootDirectoryPath, ignoredDirectoryPaths, onChange
1695
2117
  resolvedTargetPath.startsWith("".concat(resolvedIgnoredPath).concat(path.sep)));
1696
2118
  });
1697
2119
  }
2120
+ function shouldWatch(targetPath) {
2121
+ var resolvedTargetPath = path.resolve(targetPath);
2122
+ if (shouldIgnore(resolvedTargetPath)) {
2123
+ return false;
2124
+ }
2125
+ return watchPaths.some(function (watchPath) {
2126
+ var resolvedWatchPath = path.resolve(watchPath);
2127
+ return (resolvedTargetPath === resolvedWatchPath ||
2128
+ resolvedTargetPath.startsWith("".concat(resolvedWatchPath).concat(path.sep)));
2129
+ });
2130
+ }
1698
2131
  function collectSnapshotEntries(directoryPath, snapshotEntries) {
1699
2132
  if (shouldIgnore(directoryPath)) {
1700
2133
  return;
@@ -1721,8 +2154,7 @@ function createProjectWatcher(rootDirectoryPath, ignoredDirectoryPaths, onChange
1721
2154
  }
1722
2155
  try {
1723
2156
  var stat = fs.statSync(entryPath);
1724
- var relativePath = path.relative(rootDirectoryPath, entryPath);
1725
- snapshotEntries.push("".concat(relativePath, ":").concat(stat.size, ":").concat(stat.mtimeMs));
2157
+ snapshotEntries.set(entryPath, "".concat(stat.size, ":").concat(stat.mtimeMs));
1726
2158
  }
1727
2159
  catch (_b) {
1728
2160
  // Ignore transient editor save races.
@@ -1730,22 +2162,94 @@ function createProjectWatcher(rootDirectoryPath, ignoredDirectoryPaths, onChange
1730
2162
  }
1731
2163
  }
1732
2164
  function createSnapshot() {
1733
- var snapshotEntries = [];
1734
- collectSnapshotEntries(rootDirectoryPath, snapshotEntries);
1735
- snapshotEntries.sort();
1736
- return snapshotEntries.join("|");
1737
- }
1738
- var previousSnapshot = createSnapshot();
1739
- var interval = setInterval(function () {
1740
- var nextSnapshot = createSnapshot();
1741
- if (nextSnapshot === previousSnapshot) {
1742
- return;
2165
+ var snapshotEntries = new Map();
2166
+ for (var _i = 0, watchPaths_2 = watchPaths; _i < watchPaths_2.length; _i++) {
2167
+ var watchPath = watchPaths_2[_i];
2168
+ if (!fs.existsSync(watchPath)) {
2169
+ continue;
2170
+ }
2171
+ var stat = fs.statSync(watchPath);
2172
+ if (stat.isFile()) {
2173
+ snapshotEntries.set(watchPath, "".concat(stat.size, ":").concat(stat.mtimeMs));
2174
+ continue;
2175
+ }
2176
+ collectSnapshotEntries(watchPath, snapshotEntries);
2177
+ }
2178
+ return snapshotEntries;
2179
+ }
2180
+ function getSnapshotChanges(previous, next) {
2181
+ var changedPaths = new Set();
2182
+ for (var _i = 0, _a = Array.from(next.entries()); _i < _a.length; _i++) {
2183
+ var _b = _a[_i], filePath = _b[0], signature = _b[1];
2184
+ if (previous.get(filePath) !== signature) {
2185
+ changedPaths.add(filePath);
2186
+ }
2187
+ }
2188
+ for (var _c = 0, _d = Array.from(previous.keys()); _c < _d.length; _c++) {
2189
+ var filePath = _d[_c];
2190
+ if (!next.has(filePath)) {
2191
+ changedPaths.add(filePath);
2192
+ }
2193
+ }
2194
+ return Array.from(changedPaths);
2195
+ }
2196
+ function createPollingWatcher() {
2197
+ var previousSnapshot = createSnapshot();
2198
+ var interval = setInterval(function () {
2199
+ var nextSnapshot = createSnapshot();
2200
+ var changedPaths = getSnapshotChanges(previousSnapshot, nextSnapshot).filter(shouldWatch);
2201
+ previousSnapshot = nextSnapshot;
2202
+ if (changedPaths.length === 0) {
2203
+ return;
2204
+ }
2205
+ onChange(changedPaths);
2206
+ }, 1000);
2207
+ return function () {
2208
+ clearInterval(interval);
2209
+ };
2210
+ }
2211
+ var watchers = [];
2212
+ var nativeWatcherFailed = false;
2213
+ var _loop_2 = function (watchPath) {
2214
+ if (!fs.existsSync(watchPath)) {
2215
+ return "continue";
2216
+ }
2217
+ try {
2218
+ var stat = fs.statSync(watchPath);
2219
+ var directoryPath_1 = stat.isDirectory() ? watchPath : path.dirname(watchPath);
2220
+ var watcher = fs.watch(directoryPath_1, { recursive: stat.isDirectory() }, function (_eventType, filename) {
2221
+ var changedPath = filename
2222
+ ? path.resolve(directoryPath_1, filename.toString())
2223
+ : directoryPath_1;
2224
+ if (shouldWatch(changedPath)) {
2225
+ onChange([changedPath]);
2226
+ }
2227
+ });
2228
+ watchers.push(watcher);
2229
+ }
2230
+ catch (_error) {
2231
+ nativeWatcherFailed = true;
2232
+ return "break";
1743
2233
  }
1744
- previousSnapshot = nextSnapshot;
1745
- onChange(rootDirectoryPath);
1746
- }, 250);
2234
+ };
2235
+ for (var _i = 0, watchPaths_1 = watchPaths; _i < watchPaths_1.length; _i++) {
2236
+ var watchPath = watchPaths_1[_i];
2237
+ var state_2 = _loop_2(watchPath);
2238
+ if (state_2 === "break")
2239
+ break;
2240
+ }
2241
+ if (nativeWatcherFailed || watchers.length === 0) {
2242
+ for (var _a = 0, watchers_1 = watchers; _a < watchers_1.length; _a++) {
2243
+ var watcher = watchers_1[_a];
2244
+ watcher.close();
2245
+ }
2246
+ return createPollingWatcher();
2247
+ }
1747
2248
  return function () {
1748
- clearInterval(interval);
2249
+ for (var _i = 0, watchers_2 = watchers; _i < watchers_2.length; _i++) {
2250
+ var watcher = watchers_2[_i];
2251
+ watcher.close();
2252
+ }
1749
2253
  };
1750
2254
  }
1751
2255
  function serveCatalog(runtime_1, rootDirectoryPath_1, projectConfig_1, datasource_1) {
@@ -1874,13 +2378,17 @@ function isWithTranslationSearchEnabled(parsed) {
1874
2378
  function isWithDuplicatesEnabled(parsed) {
1875
2379
  return parsed.withDuplicates === true || parsed["with-duplicates"] === true;
1876
2380
  }
2381
+ exports.__catalogDevInternals = {
2382
+ classifyCatalogDevChanges: classifyCatalogDevChanges,
2383
+ getCatalogInputWatchPaths: getCatalogInputWatchPaths,
2384
+ };
1877
2385
  function createCatalogPlugin(runtime, api) {
1878
2386
  var _this = this;
1879
2387
  if (api === void 0) { api = createCatalogApi(runtime); }
1880
2388
  return {
1881
2389
  command: "catalog [subcommand]",
1882
2390
  handler: function (_a) { return __awaiter(_this, [_a], void 0, function (_b) {
1883
- var allowedSubcommands, browserRouter, withTranslationSearch, withDuplicates, server_1, outputDirectoryPath, ignoredDirectoryPaths, exportInFlight_1, exportQueued_1, queuedReason_1, debounceTimer_1, runExportAndReload_1, stopWatchingProject;
2391
+ var allowedSubcommands, browserRouter, withTranslationSearch, withDuplicates, outputDirectoryPath, devSession_1, server_1, ignoredDirectoryPaths, exportInFlight_1, queuedChanges_1, pendingChanges_1, debounceTimer_1, runRebuildAndReload_1, stopWatchingProject;
1884
2392
  var _this = this;
1885
2393
  var rootDirectoryPath = _b.rootDirectoryPath, projectConfig = _b.projectConfig, datasource = _b.datasource, parsed = _b.parsed;
1886
2394
  return __generator(this, function (_c) {
@@ -1890,16 +2398,25 @@ function createCatalogPlugin(runtime, api) {
1890
2398
  browserRouter = !(parsed.hashRouter || parsed["hash-router"]);
1891
2399
  withTranslationSearch = isWithTranslationSearchEnabled(parsed);
1892
2400
  withDuplicates = isWithDuplicatesEnabled(parsed);
1893
- if (!!parsed.subcommand) return [3 /*break*/, 3];
2401
+ if (!!parsed.subcommand) return [3 /*break*/, 4];
2402
+ outputDirectoryPath = parsed.outDir
2403
+ ? path.resolve(rootDirectoryPath, parsed.outDir)
2404
+ : projectConfig.catalogDirectoryPath;
2405
+ return [4 /*yield*/, createCatalogDevSession(rootDirectoryPath, projectConfig, {
2406
+ outDir: parsed.outDir,
2407
+ })];
2408
+ case 1:
2409
+ devSession_1 = _c.sent();
1894
2410
  return [4 /*yield*/, api.exportCatalog(rootDirectoryPath, projectConfig, datasource, {
1895
2411
  outDir: parsed.outDir,
1896
2412
  copyAssets: !parsed.noAssets,
1897
2413
  browserRouter: browserRouter,
1898
2414
  dev: true,
2415
+ devSession: devSession_1,
1899
2416
  withTranslationSearch: withTranslationSearch,
1900
2417
  withDuplicates: withDuplicates,
1901
2418
  })];
1902
- case 1:
2419
+ case 2:
1903
2420
  _c.sent();
1904
2421
  return [4 /*yield*/, api.serveCatalog(rootDirectoryPath, projectConfig, datasource, {
1905
2422
  outDir: parsed.outDir,
@@ -1907,11 +2424,8 @@ function createCatalogPlugin(runtime, api) {
1907
2424
  browserRouter: browserRouter,
1908
2425
  liveReload: true,
1909
2426
  })];
1910
- case 2:
2427
+ case 3:
1911
2428
  server_1 = _c.sent();
1912
- outputDirectoryPath = parsed.outDir
1913
- ? path.resolve(rootDirectoryPath, parsed.outDir)
1914
- : projectConfig.catalogDirectoryPath;
1915
2429
  ignoredDirectoryPaths = [
1916
2430
  path.join(rootDirectoryPath, ".git"),
1917
2431
  path.join(rootDirectoryPath, "node_modules"),
@@ -1923,72 +2437,102 @@ function createCatalogPlugin(runtime, api) {
1923
2437
  outputDirectoryPath,
1924
2438
  ];
1925
2439
  exportInFlight_1 = false;
1926
- exportQueued_1 = false;
1927
- queuedReason_1 = null;
2440
+ queuedChanges_1 = [];
2441
+ pendingChanges_1 = [];
1928
2442
  debounceTimer_1 = null;
1929
- runExportAndReload_1 = function (reason) { return __awaiter(_this, void 0, void 0, function () {
1930
- var error_1, nextReason;
2443
+ runRebuildAndReload_1 = function (changedPaths) { return __awaiter(_this, void 0, void 0, function () {
2444
+ var request, handled, execution, error_1, nextChanges;
1931
2445
  return __generator(this, function (_a) {
1932
2446
  switch (_a.label) {
1933
2447
  case 0:
1934
2448
  if (exportInFlight_1) {
1935
- exportQueued_1 = true;
1936
- queuedReason_1 = queuedReason_1 || reason;
2449
+ queuedChanges_1.push.apply(queuedChanges_1, changedPaths);
1937
2450
  return [2 /*return*/];
1938
2451
  }
1939
2452
  exportInFlight_1 = true;
1940
- console.log("\n[catalog] Re-exporting because ".concat(reason));
2453
+ request = classifyCatalogDevChanges(rootDirectoryPath, projectConfig, changedPaths, {
2454
+ withTranslationSearch: withTranslationSearch,
2455
+ withDuplicates: withDuplicates,
2456
+ });
2457
+ console.log("\n[catalog] Rebuilding (".concat(request.kind, ") because ").concat(request.reason));
1941
2458
  _a.label = 1;
1942
2459
  case 1:
1943
- _a.trys.push([1, 3, 4, 5]);
2460
+ _a.trys.push([1, 9, 10, 11]);
2461
+ handled = false;
2462
+ if (!(request.kind === "message")) return [3 /*break*/, 4];
2463
+ return [4 /*yield*/, runtime.getProjectSetExecutions(projectConfig, datasource, request.set)];
2464
+ case 2:
2465
+ execution = (_a.sent())[0];
2466
+ return [4 /*yield*/, tryRebuildCatalogMessage(runtime, rootDirectoryPath, projectConfig, execution.projectConfig, execution.datasource, devSession_1, request)];
2467
+ case 3:
2468
+ handled = _a.sent();
2469
+ _a.label = 4;
2470
+ case 4:
2471
+ if (!(!handled && request.kind === "set" && request.set)) return [3 /*break*/, 6];
2472
+ return [4 /*yield*/, rebuildCatalogSetForDev(runtime, rootDirectoryPath, projectConfig, datasource, devSession_1, {
2473
+ set: request.set,
2474
+ browserRouter: browserRouter,
2475
+ withTranslationSearch: withTranslationSearch,
2476
+ withDuplicates: withDuplicates,
2477
+ })];
2478
+ case 5:
2479
+ handled = _a.sent();
2480
+ _a.label = 6;
2481
+ case 6:
2482
+ if (!!handled) return [3 /*break*/, 8];
1944
2483
  return [4 /*yield*/, api.exportCatalog(rootDirectoryPath, projectConfig, datasource, {
1945
2484
  outDir: parsed.outDir,
1946
- copyAssets: !parsed.noAssets,
2485
+ copyAssets: false,
2486
+ preserveAssets: true,
1947
2487
  browserRouter: browserRouter,
1948
2488
  dev: true,
2489
+ devSession: devSession_1,
1949
2490
  withTranslationSearch: withTranslationSearch,
1950
2491
  withDuplicates: withDuplicates,
1951
2492
  })];
1952
- case 2:
2493
+ case 7:
1953
2494
  _a.sent();
2495
+ _a.label = 8;
2496
+ case 8:
1954
2497
  server_1.triggerReload();
1955
- return [3 /*break*/, 5];
1956
- case 3:
2498
+ return [3 /*break*/, 11];
2499
+ case 9:
1957
2500
  error_1 = _a.sent();
1958
2501
  console.error("[catalog] Export failed during watch mode");
1959
2502
  console.error(error_1);
1960
- return [3 /*break*/, 5];
1961
- case 4:
2503
+ return [3 /*break*/, 11];
2504
+ case 10:
1962
2505
  exportInFlight_1 = false;
1963
- if (exportQueued_1) {
1964
- nextReason = queuedReason_1 || "more project changes";
1965
- exportQueued_1 = false;
1966
- queuedReason_1 = null;
1967
- void runExportAndReload_1(nextReason);
2506
+ if (queuedChanges_1.length > 0) {
2507
+ nextChanges = queuedChanges_1;
2508
+ queuedChanges_1 = [];
2509
+ void runRebuildAndReload_1(nextChanges);
1968
2510
  }
1969
2511
  return [7 /*endfinally*/];
1970
- case 5: return [2 /*return*/];
2512
+ case 11: return [2 /*return*/];
1971
2513
  }
1972
2514
  });
1973
2515
  }); };
1974
- stopWatchingProject = createProjectWatcher(rootDirectoryPath, ignoredDirectoryPaths, function (changedPath) {
1975
- var reason = "project change in ".concat(path.relative(rootDirectoryPath, changedPath) || ".");
2516
+ stopWatchingProject = createCatalogInputWatcher(rootDirectoryPath, projectConfig, ignoredDirectoryPaths, function (changedPaths) {
2517
+ pendingChanges_1.push.apply(pendingChanges_1, changedPaths);
1976
2518
  if (debounceTimer_1) {
1977
2519
  clearTimeout(debounceTimer_1);
1978
2520
  }
1979
2521
  debounceTimer_1 = setTimeout(function () {
2522
+ var nextChanges = Array.from(new Set(pendingChanges_1));
2523
+ pendingChanges_1 = [];
1980
2524
  debounceTimer_1 = null;
1981
- void runExportAndReload_1(reason);
1982
- }, 150);
2525
+ void runRebuildAndReload_1(nextChanges);
2526
+ }, 250);
1983
2527
  });
1984
2528
  process.on("exit", stopWatchingProject);
1985
2529
  return [2 /*return*/];
1986
- case 3:
2530
+ case 4:
1987
2531
  if (allowedSubcommands.indexOf(parsed.subcommand) === -1) {
1988
2532
  console.log("Please specify a subcommand: `export` or `serve`");
1989
2533
  return [2 /*return*/, false];
1990
2534
  }
1991
- if (!(parsed.subcommand === "export")) return [3 /*break*/, 5];
2535
+ if (!(parsed.subcommand === "export")) return [3 /*break*/, 6];
1992
2536
  return [4 /*yield*/, api.exportCatalog(rootDirectoryPath, projectConfig, datasource, {
1993
2537
  outDir: parsed.outDir,
1994
2538
  copyAssets: !parsed.noAssets,
@@ -1996,20 +2540,20 @@ function createCatalogPlugin(runtime, api) {
1996
2540
  withTranslationSearch: withTranslationSearch,
1997
2541
  withDuplicates: withDuplicates,
1998
2542
  })];
1999
- case 4:
2000
- _c.sent();
2001
- _c.label = 5;
2002
2543
  case 5:
2003
- if (!(parsed.subcommand === "serve")) return [3 /*break*/, 7];
2544
+ _c.sent();
2545
+ _c.label = 6;
2546
+ case 6:
2547
+ if (!(parsed.subcommand === "serve")) return [3 /*break*/, 8];
2004
2548
  return [4 /*yield*/, api.serveCatalog(rootDirectoryPath, projectConfig, datasource, {
2005
2549
  outDir: parsed.outDir,
2006
2550
  port: parsed.port || parsed.p,
2007
2551
  browserRouter: browserRouter,
2008
2552
  })];
2009
- case 6:
2553
+ case 7:
2010
2554
  _c.sent();
2011
- _c.label = 7;
2012
- case 7: return [2 /*return*/];
2555
+ _c.label = 8;
2556
+ case 8: return [2 /*return*/];
2013
2557
  }
2014
2558
  });
2015
2559
  }); },