@rindo/core 3.2.0 → 3.2.1

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/compiler/rindo.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- Rindo Compiler v3.2.0 | MIT Licensed | https://rindojs.web.app
2
+ Rindo Compiler v3.2.1 | MIT Licensed | https://rindojs.web.app
3
3
  */
4
4
  (function(exports) {
5
5
  'use strict';
@@ -72,6 +72,97 @@ const DEFAULT_STYLE_MODE = '$';
72
72
  * File names and value
73
73
  */
74
74
  const COLLECTION_MANIFEST_FILE_NAME = 'collection-manifest.json';
75
+ /**
76
+ * Constant for the 'copy' output target
77
+ */
78
+ const COPY = 'copy';
79
+ /**
80
+ * Constant for the 'custom' output target
81
+ */
82
+ const CUSTOM = 'custom';
83
+ /**
84
+ * Constant for the 'dist' output target
85
+ */
86
+ const DIST = 'dist';
87
+ /**
88
+ * Constant for the 'dist-collection' output target
89
+ */
90
+ const DIST_COLLECTION = 'dist-collection';
91
+ /**
92
+ * Constant for the 'dist-custom-elements' output target
93
+ */
94
+ const DIST_CUSTOM_ELEMENTS = 'dist-custom-elements';
95
+ /**
96
+ * Constant for the 'dist-types' output target
97
+ */
98
+ const DIST_TYPES = 'dist-types';
99
+ /**
100
+ * Constant for the 'dist-hydrate-script' output target
101
+ */
102
+ const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
103
+ /**
104
+ * Constant for the 'dist-lazy' output target
105
+ */
106
+ const DIST_LAZY = 'dist-lazy';
107
+ /**
108
+ * Constant for the 'dist-lazy-loader' output target
109
+ */
110
+ const DIST_LAZY_LOADER = 'dist-lazy-loader';
111
+ /**
112
+ * Constant for the 'dist-global-styles' output target
113
+ */
114
+ const DIST_GLOBAL_STYLES = 'dist-global-styles';
115
+ /**
116
+ * Constant for the 'docs-custom' output target
117
+ */
118
+ const DOCS_CUSTOM = 'docs-custom';
119
+ /**
120
+ * Constant for the 'docs-json' output target
121
+ */
122
+ const DOCS_JSON = 'docs-json';
123
+ /**
124
+ * Constant for the 'docs-readme' output target
125
+ */
126
+ const DOCS_README = 'docs-readme';
127
+ /**
128
+ * Constant for the 'docs-vscode' output target
129
+ */
130
+ const DOCS_VSCODE = 'docs-vscode';
131
+ /**
132
+ * Constant for the 'stats' output target
133
+ */
134
+ const STATS = 'stats';
135
+ /**
136
+ * Constant for the 'www' output target
137
+ */
138
+ const WWW = 'www';
139
+ /**
140
+ * Valid output targets to specify in a Rindo config.
141
+ *
142
+ * Note that there are some output targets (e.g. `DIST_TYPES`) which are
143
+ * programmatically set as output targets by the compiler when other output
144
+ * targets (in that case `DIST`) are set, but which are _not_ supported in a
145
+ * Rindo config. This is enforced in the output target validation code.
146
+ */
147
+ const VALID_CONFIG_OUTPUT_TARGETS = [
148
+ // DIST
149
+ WWW,
150
+ DIST,
151
+ DIST_COLLECTION,
152
+ DIST_CUSTOM_ELEMENTS,
153
+ DIST_LAZY,
154
+ DIST_HYDRATE_SCRIPT,
155
+ // DOCS
156
+ DOCS_JSON,
157
+ DOCS_README,
158
+ DOCS_VSCODE,
159
+ DOCS_CUSTOM,
160
+ // MISC
161
+ COPY,
162
+ CUSTOM,
163
+ STATS,
164
+ ];
165
+ const GENERATED_DTS = 'components.d.ts';
75
166
 
76
167
  /**
77
168
  * Transform metadata about a component from the compiler to a compact form for
@@ -1199,355 +1290,6 @@ const flattenDiagnosticMessageText = (tsDiagnostic, diag) => {
1199
1290
  return result.trim();
1200
1291
  };
1201
1292
 
1202
- /**
1203
- * Converts a rollup provided source map to one that Rindo can easily understand
1204
- * @param rollupSourceMap the sourcemap to transform
1205
- * @returns the transformed sourcemap
1206
- */
1207
- const rollupToRindoSourceMap = (rollupSourceMap) => {
1208
- if (!rollupSourceMap) {
1209
- return null;
1210
- }
1211
- return {
1212
- file: rollupSourceMap.file,
1213
- mappings: rollupSourceMap.mappings,
1214
- names: rollupSourceMap.names,
1215
- sources: rollupSourceMap.sources,
1216
- sourcesContent: rollupSourceMap.sourcesContent,
1217
- version: rollupSourceMap.version,
1218
- };
1219
- };
1220
- /**
1221
- * A JavaScript formatted string used to link generated code back to the original. This string follows the guidelines
1222
- * found in the [Linking generated code to source maps](https://sourcemaps.info/spec.html#h.lmz475t4mvbx) section of
1223
- * the Sourcemaps V3 specification proposal.
1224
- */
1225
- const JS_SOURCE_MAPPING_URL_LINKER = '//# sourceMappingURL=';
1226
- /**
1227
- * Generates an RFC-3986 compliant string for the given input.
1228
- * More information about RFC-3986 can be found [here](https://datatracker.ietf.org/doc/html/rfc3986)
1229
- * This function's original source is derived from
1230
- * [MDN's encodeURIComponent documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#description)
1231
- * @param filename the filename to encode
1232
- * @returns the encoded URI
1233
- */
1234
- const encodeToRfc3986 = (filename) => {
1235
- const encodedUri = encodeURIComponent(filename);
1236
- // replace all '!', single quotes, '(', ')', and '*' with their hexadecimal values (UTF-16)
1237
- return encodedUri.replace(/[!'()*]/g, (matchedCharacter) => {
1238
- return '%' + matchedCharacter.charCodeAt(0).toString(16);
1239
- });
1240
- };
1241
- /**
1242
- * Generates a string used to link generated code with the original source, to be placed at the end of the generated
1243
- * code.
1244
- * @param url the url of the source map
1245
- * @returns a linker string, of the format {@link JS_SOURCE_MAPPING_URL_LINKER}=<url>
1246
- */
1247
- const getSourceMappingUrlLinker = (url) => {
1248
- return `${JS_SOURCE_MAPPING_URL_LINKER}${encodeToRfc3986(url)}`;
1249
- };
1250
- /**
1251
- * Generates a string used to link generated code with the original source, to be placed at the end of the generated
1252
- * code as an inline source map.
1253
- * @param sourceMapContents the sourceMapContents of the source map
1254
- * @returns a linker string, of the format {@link JS_SOURCE_MAPPING_URL_LINKER}<dataUriPrefixAndMime><sourceMapContents>
1255
- */
1256
- const getInlineSourceMappingUrlLinker = (sourceMapContents) => {
1257
- const mapBase64 = Buffer.from(sourceMapContents, 'utf8').toString('base64');
1258
- // do not RFC-3986 encode an already valid base64 string. the sourcemaps will not resolve correctly when there is an
1259
- // allowed base64 character is encoded (because it is a disallowed RFC-3986 character)
1260
- return `${JS_SOURCE_MAPPING_URL_LINKER}data:application/json;charset=utf-8;base64,${mapBase64}`;
1261
- };
1262
- /**
1263
- * Generates a string used to link generated code with the original source, to be placed at the end of the generated
1264
- * code. This function prepends a newline to the string.
1265
- * @param url the url of the source map
1266
- * @returns a linker string, of the format {@link JS_SOURCE_MAPPING_URL_LINKER}=<url>.map, prepended with a newline
1267
- */
1268
- const getSourceMappingUrlForEndOfFile = (url) => {
1269
- return `\n${getSourceMappingUrlLinker(url)}.map`;
1270
- };
1271
-
1272
- /**
1273
- * Determines whether a string should be considered a remote url or not.
1274
- *
1275
- * This helper only checks the provided string to evaluate is one of a few pre-defined schemes, and should not be
1276
- * considered all-encompassing
1277
- *
1278
- * @param p the string to evaluate
1279
- * @returns `true` if the provided string is a remote url, `false` otherwise
1280
- */
1281
- const isRemoteUrl = (p) => {
1282
- if (isString$1(p)) {
1283
- p = p.toLowerCase();
1284
- return p.startsWith('https://') || p.startsWith('http://');
1285
- }
1286
- return false;
1287
- };
1288
-
1289
- /**
1290
- * A set of JSDoc tags which should be excluded from JSDoc comments
1291
- * included in output typedefs.
1292
- */
1293
- const SUPPRESSED_JSDOC_TAGS = ['virtualProp', 'slot', 'part', 'internal'];
1294
- /**
1295
- * Create a stylistically-appropriate JS variable name from a filename
1296
- *
1297
- * If the filename has any of the special characters "?", "#", "&" and "=" it
1298
- * will take the string before the left-most instance of one of those
1299
- * characters.
1300
- *
1301
- * @param fileName the filename which serves as starting material
1302
- * @returns a JS variable name based on the filename
1303
- */
1304
- const createJsVarName = (fileName) => {
1305
- if (isString$1(fileName)) {
1306
- fileName = fileName.split('?')[0];
1307
- fileName = fileName.split('#')[0];
1308
- fileName = fileName.split('&')[0];
1309
- fileName = fileName.split('=')[0];
1310
- fileName = toDashCase(fileName);
1311
- fileName = fileName.replace(/[|;$%@"<>()+,.{}_\!\/\\]/g, '-');
1312
- fileName = dashToPascalCase$1(fileName);
1313
- if (fileName.length > 1) {
1314
- fileName = fileName[0].toLowerCase() + fileName.slice(1);
1315
- }
1316
- else {
1317
- fileName = fileName.toLowerCase();
1318
- }
1319
- if (fileName.length > 0 && !isNaN(fileName[0])) {
1320
- fileName = '_' + fileName;
1321
- }
1322
- }
1323
- return fileName;
1324
- };
1325
- /**
1326
- * Determines if a given file path points to a type declaration file (ending in .d.ts) or not. This function is
1327
- * case-insensitive in its heuristics.
1328
- * @param filePath the path to check
1329
- * @returns `true` if the given `filePath` points to a type declaration file, `false` otherwise
1330
- */
1331
- const isDtsFile$1 = (filePath) => {
1332
- const parts = filePath.toLowerCase().split('.');
1333
- if (parts.length > 2) {
1334
- return parts[parts.length - 2] === 'd' && parts[parts.length - 1] === 'ts';
1335
- }
1336
- return false;
1337
- };
1338
- /**
1339
- * Generate the preamble to be placed atop the main file of the build
1340
- * @param config the Rindo configuration file
1341
- * @returns the generated preamble
1342
- */
1343
- const generatePreamble = (config) => {
1344
- const { preamble } = config;
1345
- if (!preamble) {
1346
- return '';
1347
- }
1348
- // generate the body of the JSDoc-style comment
1349
- const preambleComment = preamble.split('\n').map((l) => ` * ${l}`);
1350
- preambleComment.unshift(`/*!`);
1351
- preambleComment.push(` */`);
1352
- return preambleComment.join('\n');
1353
- };
1354
- const lineBreakRegex = /\r?\n|\r/g;
1355
- function getTextDocs(docs) {
1356
- if (docs == null) {
1357
- return '';
1358
- }
1359
- return `${docs.text.replace(lineBreakRegex, ' ')}
1360
- ${docs.tags
1361
- .filter((tag) => tag.name !== 'internal')
1362
- .map((tag) => `@${tag.name} ${(tag.text || '').replace(lineBreakRegex, ' ')}`)
1363
- .join('\n')}`.trim();
1364
- }
1365
- /**
1366
- * Adds a doc block to a string
1367
- * @param str the string to add a doc block to
1368
- * @param docs the compiled JS docs
1369
- * @param indentation number of spaces to indent the block with
1370
- * @returns the doc block
1371
- */
1372
- function addDocBlock(str, docs, indentation = 0) {
1373
- if (!docs) {
1374
- return str;
1375
- }
1376
- return [formatDocBlock(docs, indentation), str].filter(Boolean).join(`\n`);
1377
- }
1378
- /**
1379
- * Formats the given compiled docs to a JavaScript doc block
1380
- * @param docs the compiled JS docs
1381
- * @param indentation number of spaces to indent the block with
1382
- * @returns the formatted doc block
1383
- */
1384
- function formatDocBlock(docs, indentation = 0) {
1385
- const textDocs = getDocBlockLines(docs);
1386
- if (!textDocs.filter(Boolean).length) {
1387
- return '';
1388
- }
1389
- const spaces = new Array(indentation + 1).join(' ');
1390
- return [spaces + '/**', ...textDocs.map((line) => spaces + ` * ${line}`), spaces + ' */'].join(`\n`);
1391
- }
1392
- /**
1393
- * Get all lines which are part of the doc block
1394
- *
1395
- * @param docs the compiled JS docs
1396
- * @returns list of lines part of the doc block
1397
- */
1398
- function getDocBlockLines(docs) {
1399
- return [
1400
- ...docs.text.split(lineBreakRegex),
1401
- ...docs.tags
1402
- .filter((tag) => !SUPPRESSED_JSDOC_TAGS.includes(tag.name))
1403
- .map((tag) => `@${tag.name} ${tag.text || ''}`.split(lineBreakRegex)),
1404
- ]
1405
- .flat()
1406
- .filter(Boolean);
1407
- }
1408
- /**
1409
- * Retrieve a project's dependencies from the current build context
1410
- * @param buildCtx the current build context to query for a specific package
1411
- * @returns a list of package names the project is dependent on
1412
- */
1413
- const getDependencies = (buildCtx) => {
1414
- if (buildCtx.packageJson != null && buildCtx.packageJson.dependencies != null) {
1415
- return Object.keys(buildCtx.packageJson.dependencies).filter((pkgName) => !SKIP_DEPS.includes(pkgName));
1416
- }
1417
- return [];
1418
- };
1419
- /**
1420
- * Utility to determine whether a project has a dependency on a package
1421
- * @param buildCtx the current build context to query for a specific package
1422
- * @param depName the name of the dependency/package
1423
- * @returns `true` if the project has a dependency a packaged with the provided name, `false` otherwise
1424
- */
1425
- const hasDependency = (buildCtx, depName) => {
1426
- return getDependencies(buildCtx).includes(depName);
1427
- };
1428
- // TODO: Remove code related to the dynamic import shim
1429
- const getDynamicImportFunction$1 = (namespace) => `__sc_import_${namespace.replace(/\s|-/g, '_')}`;
1430
- const readPackageJson = async (config, compilerCtx, buildCtx) => {
1431
- try {
1432
- const pkgJson = await compilerCtx.fs.readFile(config.packageJsonFilePath);
1433
- if (pkgJson) {
1434
- const parseResults = parsePackageJson(pkgJson, config.packageJsonFilePath);
1435
- if (parseResults.diagnostic) {
1436
- buildCtx.diagnostics.push(parseResults.diagnostic);
1437
- }
1438
- else {
1439
- buildCtx.packageJson = parseResults.data;
1440
- }
1441
- }
1442
- }
1443
- catch (e) {
1444
- if (!config.outputTargets.some((o) => o.type.includes('dist'))) {
1445
- const diagnostic = buildError(buildCtx.diagnostics);
1446
- diagnostic.header = `Missing "package.json"`;
1447
- diagnostic.messageText = `Valid "package.json" file is required for distribution: ${config.packageJsonFilePath}`;
1448
- }
1449
- }
1450
- };
1451
- /**
1452
- * Parse a string read from a `package.json` file
1453
- * @param pkgJsonStr the string read from a `package.json` file
1454
- * @param pkgJsonFilePath the path to the already read `package.json` file
1455
- * @returns the results of parsing the provided contents of the `package.json` file
1456
- */
1457
- const parsePackageJson = (pkgJsonStr, pkgJsonFilePath) => {
1458
- const parseResult = {
1459
- diagnostic: null,
1460
- data: null,
1461
- filePath: pkgJsonFilePath,
1462
- };
1463
- try {
1464
- parseResult.data = JSON.parse(pkgJsonStr);
1465
- }
1466
- catch (e) {
1467
- parseResult.diagnostic = buildError();
1468
- parseResult.diagnostic.absFilePath = isString$1(pkgJsonFilePath) ? pkgJsonFilePath : undefined;
1469
- parseResult.diagnostic.header = `Error Parsing JSON`;
1470
- if (e instanceof Error) {
1471
- parseResult.diagnostic.messageText = e.message;
1472
- }
1473
- }
1474
- return parseResult;
1475
- };
1476
- const SKIP_DEPS = ['@rindo/core'];
1477
- /**
1478
- * Check whether a string is a member of a ReadonlyArray<string>
1479
- *
1480
- * We need a little helper for this because unfortunately `includes` is typed
1481
- * on `ReadonlyArray<T>` as `(el: T): boolean` so a `string` cannot be passed
1482
- * to `includes` on a `ReadonlyArray` 😢 thus we have a little helper function
1483
- * where we do the type coercion just once.
1484
- *
1485
- * see microsoft/TypeScript#31018 for some discussion of this
1486
- *
1487
- * @param readOnlyArray the array we're checking
1488
- * @param maybeMember a value which is possibly a member of the array
1489
- * @returns whether the array contains the member or not
1490
- */
1491
- const readOnlyArrayHasStringMember = (readOnlyArray, maybeMember) => readOnlyArray.includes(maybeMember);
1492
-
1493
- /**
1494
- * Validates that a component tag meets required naming conventions to be used for a web component
1495
- * @param tag the tag to validate
1496
- * @returns an error message if the tag has an invalid name, undefined if the tag name passes all checks
1497
- */
1498
- const validateComponentTag = (tag) => {
1499
- // we want to check this first since we call some String.prototype methods below
1500
- if (typeof tag !== 'string') {
1501
- return `Tag "${tag}" must be a string type`;
1502
- }
1503
- if (tag !== tag.trim()) {
1504
- return `Tag can not contain white spaces`;
1505
- }
1506
- if (tag !== tag.toLowerCase()) {
1507
- return `Tag can not contain upper case characters`;
1508
- }
1509
- if (tag.length === 0) {
1510
- return `Received empty tag value`;
1511
- }
1512
- if (tag.indexOf(' ') > -1) {
1513
- return `"${tag}" tag cannot contain a space`;
1514
- }
1515
- if (tag.indexOf(',') > -1) {
1516
- return `"${tag}" tag cannot be used for multiple tags`;
1517
- }
1518
- const invalidChars = tag.replace(/\w|-/g, '');
1519
- if (invalidChars !== '') {
1520
- return `"${tag}" tag contains invalid characters: ${invalidChars}`;
1521
- }
1522
- if (tag.indexOf('-') === -1) {
1523
- return `"${tag}" tag must contain a dash (-) to work as a valid web component`;
1524
- }
1525
- if (tag.indexOf('--') > -1) {
1526
- return `"${tag}" tag cannot contain multiple dashes (--) next to each other`;
1527
- }
1528
- if (tag.indexOf('-') === 0) {
1529
- return `"${tag}" tag cannot start with a dash (-)`;
1530
- }
1531
- if (tag.lastIndexOf('-') === tag.length - 1) {
1532
- return `"${tag}" tag cannot end with a dash (-)`;
1533
- }
1534
- return undefined;
1535
- };
1536
-
1537
- const EOL = '\n';
1538
- const platform = () => OS_PLATFORM;
1539
- const os$2 = {
1540
- EOL,
1541
- platform,
1542
- };
1543
-
1544
- const os$3 = {
1545
- __proto__: null,
1546
- EOL: EOL,
1547
- platform: platform,
1548
- 'default': os$2
1549
- };
1550
-
1551
1293
  // 'path' module extracted from Node.js v8.11.1 (only the posix part)
1552
1294
 
1553
1295
  function assertPath(path) {
@@ -2117,6 +1859,407 @@ const path$6 = {
2117
1859
  'default': path$5
2118
1860
  };
2119
1861
 
1862
+ const relativeImport = (pathFrom, pathTo, ext, addPrefix = true) => {
1863
+ let relativePath = relative$1(dirname(pathFrom), dirname(pathTo));
1864
+ if (addPrefix) {
1865
+ if (relativePath === '') {
1866
+ relativePath = '.';
1867
+ }
1868
+ else if (relativePath[0] !== '.') {
1869
+ relativePath = './' + relativePath;
1870
+ }
1871
+ }
1872
+ return normalizePath$2(`${relativePath}/${basename(pathTo, ext)}`);
1873
+ };
1874
+ const getComponentsDtsSrcFilePath = (config) => join(config.srcDir, GENERATED_DTS);
1875
+ const getComponentsDtsTypesFilePath = (outputTarget) => join(outputTarget.typesDir, GENERATED_DTS);
1876
+ const isOutputTargetDist = (o) => o.type === DIST;
1877
+ const isOutputTargetDistCollection = (o) => o.type === DIST_COLLECTION;
1878
+ const isOutputTargetDistCustomElements = (o) => o.type === DIST_CUSTOM_ELEMENTS;
1879
+ const isOutputTargetCopy = (o) => o.type === COPY;
1880
+ const isOutputTargetDistLazy = (o) => o.type === DIST_LAZY;
1881
+ const isOutputTargetDistLazyLoader = (o) => o.type === DIST_LAZY_LOADER;
1882
+ const isOutputTargetDistGlobalStyles = (o) => o.type === DIST_GLOBAL_STYLES;
1883
+ const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
1884
+ const isOutputTargetCustom = (o) => o.type === CUSTOM;
1885
+ const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
1886
+ const isOutputTargetDocsReadme = (o) => o.type === DOCS_README;
1887
+ const isOutputTargetDocsJson = (o) => o.type === DOCS_JSON;
1888
+ const isOutputTargetDocsCustom = (o) => o.type === DOCS_CUSTOM;
1889
+ const isOutputTargetDocsVscode = (o) => o.type === DOCS_VSCODE;
1890
+ const isOutputTargetWww = (o) => o.type === WWW;
1891
+ const isOutputTargetStats = (o) => o.type === STATS;
1892
+ const isOutputTargetDistTypes = (o) => o.type === DIST_TYPES;
1893
+ /**
1894
+ * Retrieve the Rindo component compiler metadata from a collection of Rindo {@link Module}s
1895
+ * @param moduleFiles the collection of `Module`s to retrieve the metadata from
1896
+ * @returns the metadata, lexicographically sorted by the tag names of the components
1897
+ */
1898
+ const getComponentsFromModules = (moduleFiles) => sortBy(flatOne(moduleFiles.map((m) => m.cmps)), (c) => c.tagName);
1899
+ /**
1900
+ * Check whether a given output target is a valid one to be set in a Rindo config
1901
+ *
1902
+ * @param targetType the type which we want to check
1903
+ * @returns whether or not the targetType is a valid, configurable output target.
1904
+ */
1905
+ function isValidConfigOutputTarget(targetType) {
1906
+ // unfortunately `includes` is typed on `ReadonlyArray<T>` as `(el: T):
1907
+ // boolean` so a `string` cannot be passed to `includes` on a
1908
+ // `ReadonlyArray` 😢 thus we `as any`
1909
+ //
1910
+ // see microsoft/TypeScript#31018 for some discussion of this
1911
+ return VALID_CONFIG_OUTPUT_TARGETS.includes(targetType);
1912
+ }
1913
+
1914
+ /**
1915
+ * Converts a rollup provided source map to one that Rindo can easily understand
1916
+ * @param rollupSourceMap the sourcemap to transform
1917
+ * @returns the transformed sourcemap
1918
+ */
1919
+ const rollupToRindoSourceMap = (rollupSourceMap) => {
1920
+ if (!rollupSourceMap) {
1921
+ return null;
1922
+ }
1923
+ return {
1924
+ file: rollupSourceMap.file,
1925
+ mappings: rollupSourceMap.mappings,
1926
+ names: rollupSourceMap.names,
1927
+ sources: rollupSourceMap.sources,
1928
+ sourcesContent: rollupSourceMap.sourcesContent,
1929
+ version: rollupSourceMap.version,
1930
+ };
1931
+ };
1932
+ /**
1933
+ * A JavaScript formatted string used to link generated code back to the original. This string follows the guidelines
1934
+ * found in the [Linking generated code to source maps](https://sourcemaps.info/spec.html#h.lmz475t4mvbx) section of
1935
+ * the Sourcemaps V3 specification proposal.
1936
+ */
1937
+ const JS_SOURCE_MAPPING_URL_LINKER = '//# sourceMappingURL=';
1938
+ /**
1939
+ * Generates an RFC-3986 compliant string for the given input.
1940
+ * More information about RFC-3986 can be found [here](https://datatracker.ietf.org/doc/html/rfc3986)
1941
+ * This function's original source is derived from
1942
+ * [MDN's encodeURIComponent documentation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent#description)
1943
+ * @param filename the filename to encode
1944
+ * @returns the encoded URI
1945
+ */
1946
+ const encodeToRfc3986 = (filename) => {
1947
+ const encodedUri = encodeURIComponent(filename);
1948
+ // replace all '!', single quotes, '(', ')', and '*' with their hexadecimal values (UTF-16)
1949
+ return encodedUri.replace(/[!'()*]/g, (matchedCharacter) => {
1950
+ return '%' + matchedCharacter.charCodeAt(0).toString(16);
1951
+ });
1952
+ };
1953
+ /**
1954
+ * Generates a string used to link generated code with the original source, to be placed at the end of the generated
1955
+ * code.
1956
+ * @param url the url of the source map
1957
+ * @returns a linker string, of the format {@link JS_SOURCE_MAPPING_URL_LINKER}=<url>
1958
+ */
1959
+ const getSourceMappingUrlLinker = (url) => {
1960
+ return `${JS_SOURCE_MAPPING_URL_LINKER}${encodeToRfc3986(url)}`;
1961
+ };
1962
+ /**
1963
+ * Generates a string used to link generated code with the original source, to be placed at the end of the generated
1964
+ * code as an inline source map.
1965
+ * @param sourceMapContents the sourceMapContents of the source map
1966
+ * @returns a linker string, of the format {@link JS_SOURCE_MAPPING_URL_LINKER}<dataUriPrefixAndMime><sourceMapContents>
1967
+ */
1968
+ const getInlineSourceMappingUrlLinker = (sourceMapContents) => {
1969
+ const mapBase64 = Buffer.from(sourceMapContents, 'utf8').toString('base64');
1970
+ // do not RFC-3986 encode an already valid base64 string. the sourcemaps will not resolve correctly when there is an
1971
+ // allowed base64 character is encoded (because it is a disallowed RFC-3986 character)
1972
+ return `${JS_SOURCE_MAPPING_URL_LINKER}data:application/json;charset=utf-8;base64,${mapBase64}`;
1973
+ };
1974
+ /**
1975
+ * Generates a string used to link generated code with the original source, to be placed at the end of the generated
1976
+ * code. This function prepends a newline to the string.
1977
+ * @param url the url of the source map
1978
+ * @returns a linker string, of the format {@link JS_SOURCE_MAPPING_URL_LINKER}=<url>.map, prepended with a newline
1979
+ */
1980
+ const getSourceMappingUrlForEndOfFile = (url) => {
1981
+ return `\n${getSourceMappingUrlLinker(url)}.map`;
1982
+ };
1983
+
1984
+ /**
1985
+ * Determines whether a string should be considered a remote url or not.
1986
+ *
1987
+ * This helper only checks the provided string to evaluate is one of a few pre-defined schemes, and should not be
1988
+ * considered all-encompassing
1989
+ *
1990
+ * @param p the string to evaluate
1991
+ * @returns `true` if the provided string is a remote url, `false` otherwise
1992
+ */
1993
+ const isRemoteUrl = (p) => {
1994
+ if (isString$1(p)) {
1995
+ p = p.toLowerCase();
1996
+ return p.startsWith('https://') || p.startsWith('http://');
1997
+ }
1998
+ return false;
1999
+ };
2000
+
2001
+ /**
2002
+ * A set of JSDoc tags which should be excluded from JSDoc comments
2003
+ * included in output typedefs.
2004
+ */
2005
+ const SUPPRESSED_JSDOC_TAGS = ['virtualProp', 'slot', 'part', 'internal'];
2006
+ /**
2007
+ * Create a stylistically-appropriate JS variable name from a filename
2008
+ *
2009
+ * If the filename has any of the special characters "?", "#", "&" and "=" it
2010
+ * will take the string before the left-most instance of one of those
2011
+ * characters.
2012
+ *
2013
+ * @param fileName the filename which serves as starting material
2014
+ * @returns a JS variable name based on the filename
2015
+ */
2016
+ const createJsVarName = (fileName) => {
2017
+ if (isString$1(fileName)) {
2018
+ fileName = fileName.split('?')[0];
2019
+ fileName = fileName.split('#')[0];
2020
+ fileName = fileName.split('&')[0];
2021
+ fileName = fileName.split('=')[0];
2022
+ fileName = toDashCase(fileName);
2023
+ fileName = fileName.replace(/[|;$%@"<>()+,.{}_\!\/\\]/g, '-');
2024
+ fileName = dashToPascalCase$1(fileName);
2025
+ if (fileName.length > 1) {
2026
+ fileName = fileName[0].toLowerCase() + fileName.slice(1);
2027
+ }
2028
+ else {
2029
+ fileName = fileName.toLowerCase();
2030
+ }
2031
+ if (fileName.length > 0 && !isNaN(fileName[0])) {
2032
+ fileName = '_' + fileName;
2033
+ }
2034
+ }
2035
+ return fileName;
2036
+ };
2037
+ /**
2038
+ * Determines if a given file path points to a type declaration file (ending in .d.ts) or not. This function is
2039
+ * case-insensitive in its heuristics.
2040
+ * @param filePath the path to check
2041
+ * @returns `true` if the given `filePath` points to a type declaration file, `false` otherwise
2042
+ */
2043
+ const isDtsFile$1 = (filePath) => {
2044
+ const parts = filePath.toLowerCase().split('.');
2045
+ if (parts.length > 2) {
2046
+ return parts[parts.length - 2] === 'd' && parts[parts.length - 1] === 'ts';
2047
+ }
2048
+ return false;
2049
+ };
2050
+ /**
2051
+ * Generate the preamble to be placed atop the main file of the build
2052
+ * @param config the Rindo configuration file
2053
+ * @returns the generated preamble
2054
+ */
2055
+ const generatePreamble = (config) => {
2056
+ const { preamble } = config;
2057
+ if (!preamble) {
2058
+ return '';
2059
+ }
2060
+ // generate the body of the JSDoc-style comment
2061
+ const preambleComment = preamble.split('\n').map((l) => ` * ${l}`);
2062
+ preambleComment.unshift(`/*!`);
2063
+ preambleComment.push(` */`);
2064
+ return preambleComment.join('\n');
2065
+ };
2066
+ const lineBreakRegex = /\r?\n|\r/g;
2067
+ function getTextDocs(docs) {
2068
+ if (docs == null) {
2069
+ return '';
2070
+ }
2071
+ return `${docs.text.replace(lineBreakRegex, ' ')}
2072
+ ${docs.tags
2073
+ .filter((tag) => tag.name !== 'internal')
2074
+ .map((tag) => `@${tag.name} ${(tag.text || '').replace(lineBreakRegex, ' ')}`)
2075
+ .join('\n')}`.trim();
2076
+ }
2077
+ /**
2078
+ * Adds a doc block to a string
2079
+ * @param str the string to add a doc block to
2080
+ * @param docs the compiled JS docs
2081
+ * @param indentation number of spaces to indent the block with
2082
+ * @returns the doc block
2083
+ */
2084
+ function addDocBlock(str, docs, indentation = 0) {
2085
+ if (!docs) {
2086
+ return str;
2087
+ }
2088
+ return [formatDocBlock(docs, indentation), str].filter(Boolean).join(`\n`);
2089
+ }
2090
+ /**
2091
+ * Formats the given compiled docs to a JavaScript doc block
2092
+ * @param docs the compiled JS docs
2093
+ * @param indentation number of spaces to indent the block with
2094
+ * @returns the formatted doc block
2095
+ */
2096
+ function formatDocBlock(docs, indentation = 0) {
2097
+ const textDocs = getDocBlockLines(docs);
2098
+ if (!textDocs.filter(Boolean).length) {
2099
+ return '';
2100
+ }
2101
+ const spaces = new Array(indentation + 1).join(' ');
2102
+ return [spaces + '/**', ...textDocs.map((line) => spaces + ` * ${line}`), spaces + ' */'].join(`\n`);
2103
+ }
2104
+ /**
2105
+ * Get all lines which are part of the doc block
2106
+ *
2107
+ * @param docs the compiled JS docs
2108
+ * @returns list of lines part of the doc block
2109
+ */
2110
+ function getDocBlockLines(docs) {
2111
+ return [
2112
+ ...docs.text.split(lineBreakRegex),
2113
+ ...docs.tags
2114
+ .filter((tag) => !SUPPRESSED_JSDOC_TAGS.includes(tag.name))
2115
+ .map((tag) => `@${tag.name} ${tag.text || ''}`.split(lineBreakRegex)),
2116
+ ]
2117
+ .flat()
2118
+ .filter(Boolean);
2119
+ }
2120
+ /**
2121
+ * Retrieve a project's dependencies from the current build context
2122
+ * @param buildCtx the current build context to query for a specific package
2123
+ * @returns a list of package names the project is dependent on
2124
+ */
2125
+ const getDependencies = (buildCtx) => {
2126
+ if (buildCtx.packageJson != null && buildCtx.packageJson.dependencies != null) {
2127
+ return Object.keys(buildCtx.packageJson.dependencies).filter((pkgName) => !SKIP_DEPS.includes(pkgName));
2128
+ }
2129
+ return [];
2130
+ };
2131
+ /**
2132
+ * Utility to determine whether a project has a dependency on a package
2133
+ * @param buildCtx the current build context to query for a specific package
2134
+ * @param depName the name of the dependency/package
2135
+ * @returns `true` if the project has a dependency a packaged with the provided name, `false` otherwise
2136
+ */
2137
+ const hasDependency = (buildCtx, depName) => {
2138
+ return getDependencies(buildCtx).includes(depName);
2139
+ };
2140
+ // TODO: Remove code related to the dynamic import shim
2141
+ const getDynamicImportFunction$1 = (namespace) => `__sc_import_${namespace.replace(/\s|-/g, '_')}`;
2142
+ const readPackageJson = async (config, compilerCtx, buildCtx) => {
2143
+ try {
2144
+ const pkgJson = await compilerCtx.fs.readFile(config.packageJsonFilePath);
2145
+ if (pkgJson) {
2146
+ const parseResults = parsePackageJson(pkgJson, config.packageJsonFilePath);
2147
+ if (parseResults.diagnostic) {
2148
+ buildCtx.diagnostics.push(parseResults.diagnostic);
2149
+ }
2150
+ else {
2151
+ buildCtx.packageJson = parseResults.data;
2152
+ }
2153
+ }
2154
+ }
2155
+ catch (e) {
2156
+ if (!config.outputTargets.some((o) => o.type.includes('dist'))) {
2157
+ const diagnostic = buildError(buildCtx.diagnostics);
2158
+ diagnostic.header = `Missing "package.json"`;
2159
+ diagnostic.messageText = `Valid "package.json" file is required for distribution: ${config.packageJsonFilePath}`;
2160
+ }
2161
+ }
2162
+ };
2163
+ /**
2164
+ * Parse a string read from a `package.json` file
2165
+ * @param pkgJsonStr the string read from a `package.json` file
2166
+ * @param pkgJsonFilePath the path to the already read `package.json` file
2167
+ * @returns the results of parsing the provided contents of the `package.json` file
2168
+ */
2169
+ const parsePackageJson = (pkgJsonStr, pkgJsonFilePath) => {
2170
+ const parseResult = {
2171
+ diagnostic: null,
2172
+ data: null,
2173
+ filePath: pkgJsonFilePath,
2174
+ };
2175
+ try {
2176
+ parseResult.data = JSON.parse(pkgJsonStr);
2177
+ }
2178
+ catch (e) {
2179
+ parseResult.diagnostic = buildError();
2180
+ parseResult.diagnostic.absFilePath = isString$1(pkgJsonFilePath) ? pkgJsonFilePath : undefined;
2181
+ parseResult.diagnostic.header = `Error Parsing JSON`;
2182
+ if (e instanceof Error) {
2183
+ parseResult.diagnostic.messageText = e.message;
2184
+ }
2185
+ }
2186
+ return parseResult;
2187
+ };
2188
+ const SKIP_DEPS = ['@rindo/core'];
2189
+ /**
2190
+ * Check whether a string is a member of a ReadonlyArray<string>
2191
+ *
2192
+ * We need a little helper for this because unfortunately `includes` is typed
2193
+ * on `ReadonlyArray<T>` as `(el: T): boolean` so a `string` cannot be passed
2194
+ * to `includes` on a `ReadonlyArray` 😢 thus we have a little helper function
2195
+ * where we do the type coercion just once.
2196
+ *
2197
+ * see microsoft/TypeScript#31018 for some discussion of this
2198
+ *
2199
+ * @param readOnlyArray the array we're checking
2200
+ * @param maybeMember a value which is possibly a member of the array
2201
+ * @returns whether the array contains the member or not
2202
+ */
2203
+ const readOnlyArrayHasStringMember = (readOnlyArray, maybeMember) => readOnlyArray.includes(maybeMember);
2204
+
2205
+ /**
2206
+ * Validates that a component tag meets required naming conventions to be used for a web component
2207
+ * @param tag the tag to validate
2208
+ * @returns an error message if the tag has an invalid name, undefined if the tag name passes all checks
2209
+ */
2210
+ const validateComponentTag = (tag) => {
2211
+ // we want to check this first since we call some String.prototype methods below
2212
+ if (typeof tag !== 'string') {
2213
+ return `Tag "${tag}" must be a string type`;
2214
+ }
2215
+ if (tag !== tag.trim()) {
2216
+ return `Tag can not contain white spaces`;
2217
+ }
2218
+ if (tag !== tag.toLowerCase()) {
2219
+ return `Tag can not contain upper case characters`;
2220
+ }
2221
+ if (tag.length === 0) {
2222
+ return `Received empty tag value`;
2223
+ }
2224
+ if (tag.indexOf(' ') > -1) {
2225
+ return `"${tag}" tag cannot contain a space`;
2226
+ }
2227
+ if (tag.indexOf(',') > -1) {
2228
+ return `"${tag}" tag cannot be used for multiple tags`;
2229
+ }
2230
+ const invalidChars = tag.replace(/\w|-/g, '');
2231
+ if (invalidChars !== '') {
2232
+ return `"${tag}" tag contains invalid characters: ${invalidChars}`;
2233
+ }
2234
+ if (tag.indexOf('-') === -1) {
2235
+ return `"${tag}" tag must contain a dash (-) to work as a valid web component`;
2236
+ }
2237
+ if (tag.indexOf('--') > -1) {
2238
+ return `"${tag}" tag cannot contain multiple dashes (--) next to each other`;
2239
+ }
2240
+ if (tag.indexOf('-') === 0) {
2241
+ return `"${tag}" tag cannot start with a dash (-)`;
2242
+ }
2243
+ if (tag.lastIndexOf('-') === tag.length - 1) {
2244
+ return `"${tag}" tag cannot end with a dash (-)`;
2245
+ }
2246
+ return undefined;
2247
+ };
2248
+
2249
+ const EOL = '\n';
2250
+ const platform = () => OS_PLATFORM;
2251
+ const os$2 = {
2252
+ EOL,
2253
+ platform,
2254
+ };
2255
+
2256
+ const os$3 = {
2257
+ __proto__: null,
2258
+ EOL: EOL,
2259
+ platform: platform,
2260
+ 'default': os$2
2261
+ };
2262
+
2120
2263
  var commonjsGlobal$1 = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
2121
2264
 
2122
2265
  function createCommonjsModule$1(fn, basedir, module) {
@@ -2155,7 +2298,7 @@ const process$3 = /*#__PURE__*/Object.assign(/*#__PURE__*/Object.create(null), p
2155
2298
  'default': process_1
2156
2299
  });
2157
2300
 
2158
- const buildId = '1680872033';
2301
+ const buildId = '1682086722';
2159
2302
  const minfyJsId = 'terser5.16.1_7';
2160
2303
  const optimizeCssId = 'autoprefixer10.4.13_postcss8.4.21_7';
2161
2304
  const parse5Version = '7.1.2';
@@ -2163,8 +2306,8 @@ const rollupVersion = '2.42.3';
2163
2306
  const sizzleVersion = '2.42.3';
2164
2307
  const terserVersion = '5.16.1';
2165
2308
  const typescriptVersion = '4.9.4';
2166
- const vermoji = '🏙';
2167
- const version$3 = '3.2.0';
2309
+ const vermoji = '🎉';
2310
+ const version$3 = '3.2.1';
2168
2311
  const versions = {
2169
2312
  rindo: version$3,
2170
2313
  parse5: parse5Version,
@@ -13344,6 +13487,7 @@ const getModuleLegacy = (_config, compilerCtx, sourceFilePath) => {
13344
13487
  jsFilePath: jsFilePath,
13345
13488
  cmps: [],
13346
13489
  coreRuntimeApis: [],
13490
+ outputTargetCoreRuntimeApis: {},
13347
13491
  collectionName: null,
13348
13492
  dtsFilePath: null,
13349
13493
  excludeFromCollection: false,
@@ -13403,100 +13547,6 @@ const resetModuleLegacy = (moduleFile) => {
13403
13547
  moduleFile.potentialCmpRefs.length = 0;
13404
13548
  };
13405
13549
 
13406
- const relativeImport = (pathFrom, pathTo, ext, addPrefix = true) => {
13407
- let relativePath = relative$1(dirname(pathFrom), dirname(pathTo));
13408
- if (addPrefix) {
13409
- if (relativePath === '') {
13410
- relativePath = '.';
13411
- }
13412
- else if (relativePath[0] !== '.') {
13413
- relativePath = './' + relativePath;
13414
- }
13415
- }
13416
- return normalizePath$2(`${relativePath}/${basename(pathTo, ext)}`);
13417
- };
13418
- const getComponentsDtsSrcFilePath = (config) => join(config.srcDir, GENERATED_DTS);
13419
- const getComponentsDtsTypesFilePath = (outputTarget) => join(outputTarget.typesDir, GENERATED_DTS);
13420
- const isOutputTargetDist = (o) => o.type === DIST;
13421
- const isOutputTargetDistCollection = (o) => o.type === DIST_COLLECTION;
13422
- const isOutputTargetDistCustomElements = (o) => o.type === DIST_CUSTOM_ELEMENTS;
13423
- // TODO: fully delete dist-custom-elements-bundle code
13424
- const isOutputTargetDistCustomElementsBundle = (o) => o.type === DIST_CUSTOM_ELEMENTS_BUNDLE;
13425
- const isOutputTargetCopy = (o) => o.type === COPY;
13426
- const isOutputTargetDistLazy = (o) => o.type === DIST_LAZY;
13427
- const isOutputTargetDistLazyLoader = (o) => o.type === DIST_LAZY_LOADER;
13428
- const isOutputTargetDistGlobalStyles = (o) => o.type === DIST_GLOBAL_STYLES;
13429
- const isOutputTargetHydrate = (o) => o.type === DIST_HYDRATE_SCRIPT;
13430
- const isOutputTargetCustom = (o) => o.type === CUSTOM;
13431
- const isOutputTargetDocs = (o) => o.type === DOCS_README || o.type === DOCS_JSON || o.type === DOCS_CUSTOM || o.type === DOCS_VSCODE;
13432
- const isOutputTargetDocsReadme = (o) => o.type === DOCS_README;
13433
- const isOutputTargetDocsJson = (o) => o.type === DOCS_JSON;
13434
- const isOutputTargetDocsCustom = (o) => o.type === DOCS_CUSTOM;
13435
- const isOutputTargetDocsVscode = (o) => o.type === DOCS_VSCODE;
13436
- const isOutputTargetWww = (o) => o.type === WWW;
13437
- const isOutputTargetStats = (o) => o.type === STATS;
13438
- const isOutputTargetDistTypes = (o) => o.type === DIST_TYPES;
13439
- const getComponentsFromModules = (moduleFiles) => sortBy(flatOne(moduleFiles.map((m) => m.cmps)), (c) => c.tagName);
13440
- const COPY = 'copy';
13441
- const CUSTOM = 'custom';
13442
- const DIST = 'dist';
13443
- const DIST_COLLECTION = 'dist-collection';
13444
- const DIST_CUSTOM_ELEMENTS = 'dist-custom-elements';
13445
- // TODO: fully delete dist-custom-elements-bundle code
13446
- const DIST_CUSTOM_ELEMENTS_BUNDLE = 'dist-custom-elements-bundle';
13447
- const DIST_TYPES = 'dist-types';
13448
- const DIST_HYDRATE_SCRIPT = 'dist-hydrate-script';
13449
- const DIST_LAZY = 'dist-lazy';
13450
- const DIST_LAZY_LOADER = 'dist-lazy-loader';
13451
- const DIST_GLOBAL_STYLES = 'dist-global-styles';
13452
- const DOCS_CUSTOM = 'docs-custom';
13453
- const DOCS_JSON = 'docs-json';
13454
- const DOCS_README = 'docs-readme';
13455
- const DOCS_VSCODE = 'docs-vscode';
13456
- const STATS = 'stats';
13457
- const WWW = 'www';
13458
- /**
13459
- * Valid output targets to specify in a Rindo config.
13460
- *
13461
- * Note that there are some output targets (e.g. `DIST_TYPES`) which are
13462
- * programmatically set as output targets by the compiler when other output
13463
- * targets (in that case `DIST`) are set, but which are _not_ supported in a
13464
- * Rindo config. This is enforced in the output target validation code.
13465
- */
13466
- const VALID_CONFIG_OUTPUT_TARGETS = [
13467
- // DIST
13468
- WWW,
13469
- DIST,
13470
- DIST_COLLECTION,
13471
- DIST_CUSTOM_ELEMENTS,
13472
- DIST_LAZY,
13473
- DIST_HYDRATE_SCRIPT,
13474
- // DOCS
13475
- DOCS_JSON,
13476
- DOCS_README,
13477
- DOCS_VSCODE,
13478
- DOCS_CUSTOM,
13479
- // MISC
13480
- COPY,
13481
- CUSTOM,
13482
- STATS,
13483
- ];
13484
- /**
13485
- * Check whether a given output target is a valid one to be set in a Rindo config
13486
- *
13487
- * @param targetType the type which we want to check
13488
- * @returns whether or not the targetType is a valid, configurable output target.
13489
- */
13490
- function isValidConfigOutputTarget(targetType) {
13491
- // unfortunately `includes` is typed on `ReadonlyArray<T>` as `(el: T):
13492
- // boolean` so a `string` cannot be passed to `includes` on a
13493
- // `ReadonlyArray` 😢 thus we `as any`
13494
- //
13495
- // see microsoft/TypeScript#31018 for some discussion of this
13496
- return VALID_CONFIG_OUTPUT_TARGETS.includes(targetType);
13497
- }
13498
- const GENERATED_DTS = 'components.d.ts';
13499
-
13500
13550
  /**
13501
13551
  * Derive a {@link ts.CompilerOptions} object from the options currently set
13502
13552
  * on the user-supplied configuration object.
@@ -17509,9 +17559,14 @@ class MockWindow {
17509
17559
  this.__location = val;
17510
17560
  }
17511
17561
  }
17512
- matchMedia() {
17562
+ matchMedia(media) {
17513
17563
  return {
17564
+ media,
17514
17565
  matches: false,
17566
+ addEventListener,
17567
+ dispatchEvent,
17568
+ removeEventListener,
17569
+ onchange: null,
17515
17570
  };
17516
17571
  }
17517
17572
  get Node() {
@@ -19801,6 +19856,13 @@ const objectToObjectLiteral = (obj, refs) => {
19801
19856
  const createStaticGetter = (propName, returnExpression) => {
19802
19857
  return t.factory.createGetAccessorDeclaration([t.factory.createToken(t.SyntaxKind.StaticKeyword)], propName, [], undefined, t.factory.createBlock([t.factory.createReturnStatement(returnExpression)]));
19803
19858
  };
19859
+ /**
19860
+ * Retrieves a value represented by TypeScript's syntax tree by name of a static getter. The value is transformed to a
19861
+ * runtime value.
19862
+ * @param staticMembers a collection of static getters to search
19863
+ * @param staticName the name of the static getter to pull a value from
19864
+ * @returns a TypeScript value, converted from its TypeScript syntax tree representation
19865
+ */
19804
19866
  const getStaticValue = (staticMembers, staticName) => {
19805
19867
  const staticMember = staticMembers.find((member) => member.name.escapedText === staticName);
19806
19868
  if (!staticMember || !staticMember.body || !staticMember.body.statements) {
@@ -20195,15 +20257,32 @@ const parseDocsType = (checker, type, parts) => {
20195
20257
  parts.add(text);
20196
20258
  }
20197
20259
  };
20260
+ /**
20261
+ * Retrieves a Rindo `Module` entity from the compiler context for a given TypeScript `SourceFile`
20262
+ * @param compilerCtx the current compiler context to retrieve the `Module` from
20263
+ * @param tsSourceFile the TypeScript compiler `SourceFile` entity to use to retrieve the `Module`
20264
+ * @returns the `Module`, or `undefined` if it cannot be found
20265
+ */
20198
20266
  const getModuleFromSourceFile = (compilerCtx, tsSourceFile) => {
20199
20267
  const sourceFilePath = normalizePath$2(tsSourceFile.fileName);
20200
20268
  const moduleFile = compilerCtx.moduleMap.get(sourceFilePath);
20201
20269
  if (moduleFile != null) {
20202
20270
  return moduleFile;
20203
20271
  }
20272
+ // a key with the `Module`'s filename could not be found, attempt to resolve it by iterating over all modules in the
20273
+ // compiler context
20204
20274
  const moduleFiles = Array.from(compilerCtx.moduleMap.values());
20205
20275
  return moduleFiles.find((m) => m.jsFilePath === sourceFilePath);
20206
20276
  };
20277
+ /**
20278
+ * Retrieve the Rindo metadata for a component from the current compiler context, based on the provided TypeScript
20279
+ * syntax tree node. The TypeScript source file is used as a fallback in the event the metadata cannot be found based
20280
+ * on the TypeScript node.
20281
+ * @param compilerCtx the current compiler context
20282
+ * @param tsSourceFile the TypeScript `SourceFile` entity
20283
+ * @param node a TypeScript class representation of a Rindo component
20284
+ * @returns the found metadata, or `undefined` if it cannot be found
20285
+ */
20207
20286
  const getComponentMeta = (compilerCtx, tsSourceFile, node) => {
20208
20287
  const meta = compilerCtx.nodeMap.get(node);
20209
20288
  if (meta) {
@@ -20219,6 +20298,11 @@ const getComponentMeta = (compilerCtx, tsSourceFile, node) => {
20219
20298
  }
20220
20299
  return undefined;
20221
20300
  };
20301
+ /**
20302
+ * Retrieves the tag name associated with a Rindo component, based on the 'is' static getter assigned to the class at compile time
20303
+ * @param staticMembers the static getters belonging to the Rindo component class
20304
+ * @returns the tage name, or null if one cannot be found
20305
+ */
20222
20306
  const getComponentTagName = (staticMembers) => {
20223
20307
  if (staticMembers.length > 0) {
20224
20308
  const tagName = getStaticValue(staticMembers, 'is');
@@ -58669,8 +58753,23 @@ const getTsResolveExtension = (p) => {
58669
58753
  };
58670
58754
  const shouldPatchRemoteTypeScript = (compilerExe) => !IS_NODE_ENV && isRemoteUrl(compilerExe);
58671
58755
 
58756
+ /**
58757
+ * Helper function for retrieving a Rindo {@link Module} from the provided compiler context
58758
+ * @param compilerCtx the compiler context to retrieve the `Module` from
58759
+ * @param filePath the path of the file corresponding to the `Module` to lookup
58760
+ * @returns the `Module`, or `undefined` if one cannot be found
58761
+ */
58672
58762
  const getModule = (compilerCtx, filePath) => compilerCtx.moduleMap.get(normalizePath$2(filePath));
58673
- const createModule = (staticSourceFile, // this is NOT the original
58763
+ /**
58764
+ * Creates a {@link Module} entity with reasonable defaults
58765
+ * @param staticSourceFile the TypeScript representation of the source file. This may not be the original
58766
+ * representation of the file, but instead a new `SourceFile` created using the TypeScript API
58767
+ * @param staticSourceFileText the text from the `SourceFile`. This text may originate from the original representation
58768
+ * of the file.
58769
+ * @param emitFilepath the path of the JavaScript file that should be emitted after transpilation
58770
+ * @returns the created `Module`
58771
+ */
58772
+ const createModule = (staticSourceFile, // this may NOT be the original
58674
58773
  staticSourceFileText, emitFilepath) => ({
58675
58774
  sourceFilePath: normalizePath$2(staticSourceFile.fileName),
58676
58775
  jsFilePath: emitFilepath,
@@ -58678,6 +58777,7 @@ staticSourceFileText, emitFilepath) => ({
58678
58777
  staticSourceFileText,
58679
58778
  cmps: [],
58680
58779
  coreRuntimeApis: [],
58780
+ outputTargetCoreRuntimeApis: {},
58681
58781
  collectionName: null,
58682
58782
  dtsFilePath: null,
58683
58783
  excludeFromCollection: false,
@@ -59479,11 +59579,37 @@ const RUNTIME_APIS = {
59479
59579
  registerHost: `registerHost as ${REGISTER_HOST}`,
59480
59580
  registerInstance: `registerInstance as ${REGISTER_INSTANCE}`,
59481
59581
  };
59582
+ /**
59583
+ * Update a Rindo Module entity to include a {@link RUNTIME_APIS} entry if it does not already exist.
59584
+ * This allows Rindo to keep `moduleFile` easily serializable, where this helper function treats the data structure
59585
+ * that stores {@link Module#coreRuntimeApis} similar to a JS `Set`.
59586
+ * @param moduleFile the Module entity to update
59587
+ * @param coreRuntimeApi the API to add to the provided module
59588
+ */
59482
59589
  const addCoreRuntimeApi = (moduleFile, coreRuntimeApi) => {
59483
59590
  if (!moduleFile.coreRuntimeApis.includes(coreRuntimeApi)) {
59484
59591
  moduleFile.coreRuntimeApis.push(coreRuntimeApi);
59485
59592
  }
59486
59593
  };
59594
+ /**
59595
+ * Update a Rindo Module entity to include a {@link RUNTIME_APIS} entry for a specific output target, if it does not
59596
+ * already exist.
59597
+ * This allows Rindo to keep `moduleFile` easily serializable, where this helper function treats the data structure
59598
+ * that stores {@link Module#outputTargetCoreRuntimeApis} similar to a JS `Set`.
59599
+ * @param moduleFile the Module entity to update
59600
+ * @param outputTarget the output target to assign the provided runtime api under
59601
+ * @param coreRuntimeApi the API to add to the provided module
59602
+ */
59603
+ const addOutputTargetCoreRuntimeApi = (moduleFile, outputTarget, coreRuntimeApi) => {
59604
+ if (!moduleFile.outputTargetCoreRuntimeApis[outputTarget]) {
59605
+ // no such output target-specific collection exists, create the empty collection
59606
+ moduleFile.outputTargetCoreRuntimeApis[outputTarget] = [];
59607
+ }
59608
+ if (!moduleFile.outputTargetCoreRuntimeApis[outputTarget].includes(coreRuntimeApi)) {
59609
+ // add the api to the collection
59610
+ moduleFile.outputTargetCoreRuntimeApis[outputTarget].push(coreRuntimeApi);
59611
+ }
59612
+ };
59487
59613
  const addLegacyApis = (moduleFile) => {
59488
59614
  addCoreRuntimeApi(moduleFile, RUNTIME_APIS.legacyH);
59489
59615
  };
@@ -59491,12 +59617,9 @@ const addLegacyApis = (moduleFile) => {
59491
59617
  const addModuleMetadataProxies = (tsSourceFile, moduleFile) => {
59492
59618
  const statements = tsSourceFile.statements.slice();
59493
59619
  addCoreRuntimeApi(moduleFile, RUNTIME_APIS.proxyCustomElement);
59494
- statements.push(...moduleFile.cmps.map(addComponentMetadataProxy));
59620
+ statements.push(...moduleFile.cmps.map(createComponentMetadataProxy));
59495
59621
  return t.factory.updateSourceFile(tsSourceFile, statements);
59496
59622
  };
59497
- const addComponentMetadataProxy = (compilerMeta) => {
59498
- return t.factory.createExpressionStatement(createComponentMetadataProxy(compilerMeta));
59499
- };
59500
59623
  /**
59501
59624
  * Create a call expression for wrapping a component in a proxy. This call expression takes a form:
59502
59625
  * ```ts
@@ -59504,7 +59627,7 @@ const addComponentMetadataProxy = (compilerMeta) => {
59504
59627
  * ```
59505
59628
  * where
59506
59629
  * - `PROXY_CUSTOM_ELEMENT` is a Rindo internal identifier that will be replaced with the name of the actual function
59507
- * name at compile name
59630
+ * name at compile time
59508
59631
  * - `ComponentClassName` is the name Rindo component's class
59509
59632
  * - `Metadata` is the compiler metadata associated with the Rindo component
59510
59633
  *
@@ -59515,30 +59638,49 @@ const createComponentMetadataProxy = (compilerMeta) => {
59515
59638
  const compactMeta = formatComponentRuntimeMeta(compilerMeta, true);
59516
59639
  const literalCmpClassName = t.factory.createIdentifier(compilerMeta.componentClassName);
59517
59640
  const literalMeta = convertValueToLiteral(compactMeta);
59518
- return t.factory.createCallExpression(t.factory.createIdentifier(PROXY_CUSTOM_ELEMENT), [], [literalCmpClassName, literalMeta]);
59641
+ return t.factory.createExpressionStatement(t.factory.createCallExpression(t.factory.createIdentifier(PROXY_CUSTOM_ELEMENT), [], [literalCmpClassName, literalMeta]));
59519
59642
  };
59520
59643
  /**
59521
- * Create a call expression for wrapping a component represented as an anonymous class in a proxy. This call expression
59522
- * takes a form:
59644
+ * Create a call expression for wrapping a component represented as a class
59645
+ * expression in a proxy. This call expression takes the form:
59646
+ *
59523
59647
  * ```ts
59524
59648
  * PROXY_CUSTOM_ELEMENT(Clazz, Metadata);
59525
59649
  * ```
59650
+ *
59526
59651
  * where
59527
- * - `PROXY_CUSTOM_ELEMENT` is a Rindo internal identifier that will be replaced with the name of the actual function
59528
- * name at compile name
59529
- * - `Clazz` is an anonymous class to be proxied
59652
+ * - `PROXY_CUSTOM_ELEMENT` is a Rindo internal identifier that will be
59653
+ * replaced with the name of the actual function name at compile time
59654
+ * - `Clazz` is a class expression to be proxied
59530
59655
  * - `Metadata` is the compiler metadata associated with the Rindo component
59531
59656
  *
59532
- * @param compilerMeta compiler metadata associated with the component to be wrapped in a proxy
59533
- * @param clazz the anonymous class to proxy
59657
+ * @param compilerMeta compiler metadata associated with the component to be
59658
+ * wrapped in a proxy
59659
+ * @param clazz the class expression to proxy
59534
59660
  * @returns the generated call expression
59535
59661
  */
59536
- const createAnonymousClassMetadataProxy = (compilerMeta, clazz) => {
59662
+ const createClassMetadataProxy = (compilerMeta, clazz) => {
59537
59663
  const compactMeta = formatComponentRuntimeMeta(compilerMeta, true);
59538
59664
  const literalMeta = convertValueToLiteral(compactMeta);
59539
59665
  return t.factory.createCallExpression(t.factory.createIdentifier(PROXY_CUSTOM_ELEMENT), [], [clazz, literalMeta]);
59540
59666
  };
59541
59667
 
59668
+ /**
59669
+ * Create a new import statement, and update the provided source file with the newly created statement.
59670
+ *
59671
+ * The generated import statement will be placed at the beginning of the source file.
59672
+ *
59673
+ * The generated import statement will be either a commonjs require statement or esm import statement, based on the
59674
+ * provided transform options.
59675
+ *
59676
+ * The import statement may include more than one named imports (identifiers) for the provided import path.
59677
+ *
59678
+ * @param transformOpts transform options configured for the current output target transpilation
59679
+ * @param tsSourceFile the TypeScript source file that is being updated
59680
+ * @param importFnNames a collection of named imports to add to the generated import statement
59681
+ * @param importPath the path to the module that the collection of named imports should be imported from
59682
+ * @returns the updated TypeScript source file
59683
+ */
59542
59684
  const addImports = (transformOpts, tsSourceFile, importFnNames, importPath) => {
59543
59685
  if (importFnNames.length === 0) {
59544
59686
  return tsSourceFile;
@@ -59592,8 +59734,13 @@ const proxyCustomElement = (compilerCtx, transformOpts) => {
59592
59734
  if (declaration.name.getText() !== principalComponent.componentClassName) {
59593
59735
  continue;
59594
59736
  }
59737
+ // to narrow the type of `declaration.initializer` to `ts.ClassExpression`
59738
+ if (!t.isClassExpression(declaration.initializer)) {
59739
+ continue;
59740
+ }
59741
+ const renamedClassExpression = t.factory.updateClassExpression(declaration.initializer, t.getModifiers(declaration.initializer), t.factory.createIdentifier(principalComponent.componentClassName), declaration.initializer.typeParameters, declaration.initializer.heritageClauses, declaration.initializer.members);
59595
59742
  // wrap the Rindo component's class declaration in a component proxy
59596
- const proxyCreationCall = createAnonymousClassMetadataProxy(principalComponent, declaration.initializer);
59743
+ const proxyCreationCall = createClassMetadataProxy(principalComponent, renamedClassExpression);
59597
59744
  t.addSyntheticLeadingComment(proxyCreationCall, t.SyntaxKind.MultiLineCommentTrivia, '@__PURE__', false);
59598
59745
  // update the component's variable declaration to use the new initializer
59599
59746
  const proxiedComponentDeclaration = t.factory.updateVariableDeclaration(declaration, declaration.name, declaration.exclamationToken, declaration.type, proxyCreationCall);
@@ -59797,6 +59944,13 @@ const syntheticRender = (moduleFile, hasRender) => {
59797
59944
  };
59798
59945
  const INTERNAL_RENDER = '__rindo_render';
59799
59946
 
59947
+ /**
59948
+ * Creates a new collection of class members that belong to the provided class node and that do not exist in
59949
+ * {@link REMOVE_STATIC_GETTERS}
59950
+ * @param classNode the class node in the syntax tree to inspect
59951
+ * @returns a new collection of class members belonging to the provided class node, less those found in
59952
+ * {@link REMOVE_STATIC_GETTERS}
59953
+ */
59800
59954
  const removeStaticMetaProperties = (classNode) => {
59801
59955
  if (classNode.members == null) {
59802
59956
  return [];
@@ -59812,6 +59966,9 @@ const removeStaticMetaProperties = (classNode) => {
59812
59966
  return true;
59813
59967
  });
59814
59968
  };
59969
+ /**
59970
+ * A list of static getter names that are specific to Rindo to exclude from a class's member list
59971
+ */
59815
59972
  const REMOVE_STATIC_GETTERS = new Set([
59816
59973
  'is',
59817
59974
  'properties',
@@ -59897,9 +60054,17 @@ const addNativeConnectedCallback = (classMembers, cmp) => {
59897
60054
  }
59898
60055
  };
59899
60056
 
60057
+ /**
60058
+ * For a Rindo component, generate the code to create custom emitted events, based on `@Event()` decorators
60059
+ * @param moduleFile the 'home module' of the class for which code is being generated
60060
+ * @param cmp the component metadata associated with the provided module
60061
+ * @returns the generated event creation code
60062
+ */
59900
60063
  const addCreateEvents = (moduleFile, cmp) => {
59901
60064
  return cmp.events.map((ev) => {
59902
60065
  addCoreRuntimeApi(moduleFile, RUNTIME_APIS.createEvent);
60066
+ // for `@Event('eventName', { <eventOptions> }`, generate assignment to the class constructor of the form:
60067
+ // this.eventName = createEvent(this, 'eventName', eventOptionsAsBitwiseNumber);
59903
60068
  return t.factory.createExpressionStatement(t.factory.createAssignment(t.factory.createPropertyAccessExpression(t.factory.createThis(), t.factory.createIdentifier(ev.method)), t.factory.createCallExpression(t.factory.createIdentifier(CREATE_EVENT), undefined, [
59904
60069
  t.factory.createThis(),
59905
60070
  t.factory.createStringLiteral(ev.name),
@@ -59907,6 +60072,15 @@ const addCreateEvents = (moduleFile, cmp) => {
59907
60072
  ])));
59908
60073
  });
59909
60074
  };
60075
+ /**
60076
+ * Generate a bit flag encoded with event behavior information.
60077
+ *
60078
+ * This function uses the provided event metadata to determine which flags are set. {@link EVENT_FLAGS} acts as the
60079
+ * backing data structure that sets the actual bits on the returned value.
60080
+ *
60081
+ * @param eventMeta the metadata associated with the event
60082
+ * @returns the encoded event behaviors
60083
+ */
59910
60084
  const computeFlags = (eventMeta) => {
59911
60085
  let flags = 0;
59912
60086
  if (eventMeta.bubbles) {
@@ -59940,7 +60114,21 @@ const getStatement = (propName, method, arg) => {
59940
60114
  ])));
59941
60115
  };
59942
60116
 
59943
- const updateNativeConstructor = (classMembers, moduleFile, cmp, ensureSuper) => {
60117
+ /**
60118
+ * Updates a constructor to include:
60119
+ * - a `super()` call
60120
+ * - function calls to initialize the component
60121
+ * - function calls to create custom event emitters
60122
+ * If a constructor does not exist, one will be created
60123
+ *
60124
+ * The constructor will be added to the provided list of {@link ts.ClassElement}s in place
60125
+ *
60126
+ * @param classMembers the class elements to modify
60127
+ * @param moduleFile the Rindo module representation of the component class
60128
+ * @param cmp the component metadata generated for the component
60129
+ */
60130
+ const updateNativeConstructor = (classMembers, moduleFile, cmp) => {
60131
+ var _a, _b;
59944
60132
  if (cmp.isPlain) {
59945
60133
  return;
59946
60134
  }
@@ -59948,30 +60136,28 @@ const updateNativeConstructor = (classMembers, moduleFile, cmp, ensureSuper) =>
59948
60136
  if (cstrMethodIndex >= 0) {
59949
60137
  // add to the existing constructor()
59950
60138
  const cstrMethod = classMembers[cstrMethodIndex];
60139
+ // a constructor may not have a body (e.g. in the case of constructor overloads)
60140
+ const cstrBodyStatements = (_b = (_a = cstrMethod.body) === null || _a === void 0 ? void 0 : _a.statements) !== null && _b !== void 0 ? _b : t.factory.createNodeArray();
59951
60141
  let statements = [
59952
60142
  ...nativeInit(moduleFile, cmp),
59953
60143
  ...addCreateEvents(moduleFile, cmp),
59954
- ...cstrMethod.body.statements,
60144
+ ...cstrBodyStatements,
59955
60145
  ...addLegacyProps(moduleFile, cmp),
59956
60146
  ];
59957
- if (ensureSuper) {
59958
- const hasSuper = cstrMethod.body.statements.some((s) => s.kind === t.SyntaxKind.SuperKeyword);
59959
- if (!hasSuper) {
59960
- statements = [createNativeConstructorSuper(), ...statements];
59961
- }
60147
+ const hasSuper = cstrBodyStatements.some((s) => s.kind === t.SyntaxKind.SuperKeyword);
60148
+ if (!hasSuper) {
60149
+ statements = [createNativeConstructorSuper(), ...statements];
59962
60150
  }
59963
60151
  classMembers[cstrMethodIndex] = t.factory.updateConstructorDeclaration(cstrMethod, retrieveTsModifiers(cstrMethod), cstrMethod.parameters, t.factory.updateBlock(cstrMethod.body, statements));
59964
60152
  }
59965
60153
  else {
59966
60154
  // create a constructor()
59967
- let statements = [
60155
+ const statements = [
60156
+ createNativeConstructorSuper(),
59968
60157
  ...nativeInit(moduleFile, cmp),
59969
60158
  ...addCreateEvents(moduleFile, cmp),
59970
60159
  ...addLegacyProps(moduleFile, cmp),
59971
60160
  ];
59972
- if (ensureSuper) {
59973
- statements = [createNativeConstructorSuper(), ...statements];
59974
- }
59975
60161
  const cstrMethod = t.factory.createConstructorDeclaration(undefined, [], t.factory.createBlock(statements, true));
59976
60162
  classMembers.unshift(cstrMethod);
59977
60163
  }
@@ -59989,7 +60175,13 @@ const nativeInit = (moduleFile, cmp) => {
59989
60175
  }
59990
60176
  return initStatements;
59991
60177
  };
60178
+ /**
60179
+ * Generate an expression statement to register a host element with its VDOM equivalent in a global element-to-vdom
60180
+ * mapping.
60181
+ * @returns the generated expression statement
60182
+ */
59992
60183
  const nativeRegisterHostStatement = () => {
60184
+ // Create an expression statement, `this.__registerHost();`
59993
60185
  return t.factory.createExpressionStatement(t.factory.createCallExpression(t.factory.createPropertyAccessExpression(t.factory.createThis(), t.factory.createIdentifier('__registerHost')), undefined, undefined));
59994
60186
  };
59995
60187
  /**
@@ -59998,12 +60190,16 @@ const nativeRegisterHostStatement = () => {
59998
60190
  * @returns the generated expression statement
59999
60191
  */
60000
60192
  const nativeAttachShadowStatement = (moduleFile) => {
60001
- addCoreRuntimeApi(moduleFile, RUNTIME_APIS.attachShadow);
60193
+ addOutputTargetCoreRuntimeApi(moduleFile, DIST_CUSTOM_ELEMENTS, RUNTIME_APIS.attachShadow);
60002
60194
  // Create an expression statement, `this.__attachShadow();`
60003
60195
  return t.factory.createExpressionStatement(t.factory.createCallExpression(t.factory.createPropertyAccessExpression(t.factory.createThis(), t.factory.createIdentifier('__attachShadow')), undefined, undefined));
60004
60196
  };
60197
+ /**
60198
+ * Create an expression statement for calling `super()` for a class.
60199
+ * @returns the generated expression statement
60200
+ */
60005
60201
  const createNativeConstructorSuper = () => {
60006
- return t.factory.createExpressionStatement(t.factory.createCallExpression(t.factory.createIdentifier('super'), undefined, undefined));
60202
+ return t.factory.createExpressionStatement(t.factory.createCallExpression(t.factory.createSuper(), undefined, undefined));
60007
60203
  };
60008
60204
 
60009
60205
  const addNativeElementGetter = (classMembers, cmp) => {
@@ -60107,11 +60303,19 @@ const updateNativeComponentClass = (transformOpts, classNode, moduleFile, cmp) =
60107
60303
  const members = updateNativeHostComponentMembers(transformOpts, classNode, moduleFile, cmp);
60108
60304
  return updateComponentClass(transformOpts, classNode, heritageClauses, members);
60109
60305
  };
60306
+ /**
60307
+ * Generate a heritage clause (e.g. `extends [IDENTIFIER]`) for a Rindo component to extend `HTMLElement`
60308
+ * @param classNode the syntax tree of the Rindo component class to update
60309
+ * @param moduleFile the Rindo Module associated with the provided class node
60310
+ * @returns the generated heritage clause
60311
+ */
60110
60312
  const updateNativeHostComponentHeritageClauses = (classNode, moduleFile) => {
60111
60313
  if (classNode.heritageClauses != null && classNode.heritageClauses.length > 0) {
60314
+ // the syntax tree has a heritage clause already, don't generate a new one
60112
60315
  return classNode.heritageClauses;
60113
60316
  }
60114
60317
  if (moduleFile.cmps.length >= 1) {
60318
+ // we'll need to import `HTMLElement` in order to extend it
60115
60319
  addCoreRuntimeApi(moduleFile, RUNTIME_APIS.HTMLElement);
60116
60320
  }
60117
60321
  const heritageClause = t.factory.createHeritageClause(t.SyntaxKind.ExtendsKeyword, [
@@ -60121,7 +60325,7 @@ const updateNativeHostComponentHeritageClauses = (classNode, moduleFile) => {
60121
60325
  };
60122
60326
  const updateNativeHostComponentMembers = (transformOpts, classNode, moduleFile, cmp) => {
60123
60327
  const classMembers = removeStaticMetaProperties(classNode);
60124
- updateNativeConstructor(classMembers, moduleFile, cmp, true);
60328
+ updateNativeConstructor(classMembers, moduleFile, cmp);
60125
60329
  addNativeConnectedCallback(classMembers, cmp);
60126
60330
  addNativeElementGetter(classMembers, cmp);
60127
60331
  addWatchers(classMembers, cmp);
@@ -60135,10 +60339,24 @@ const updateNativeHostComponentMembers = (transformOpts, classNode, moduleFile,
60135
60339
  return classMembers;
60136
60340
  };
60137
60341
 
60342
+ /**
60343
+ * A function that returns a transformation factory. The returned factory performs a series of transformations on
60344
+ * Rindo components, in order to generate 'native' web components.
60345
+ * @param compilerCtx the current compiler context, which acts as the source of truth for the transformations
60346
+ * @param transformOpts the transformation configuration to use when performing the transformations
60347
+ * @returns a transformer factory, to be run by the TypeScript compiler
60348
+ */
60138
60349
  const nativeComponentTransform = (compilerCtx, transformOpts) => {
60139
60350
  return (transformCtx) => {
60140
60351
  return (tsSourceFile) => {
60352
+ var _a, _b;
60141
60353
  const moduleFile = getModuleFromSourceFile(compilerCtx, tsSourceFile);
60354
+ /**
60355
+ * Helper function that recursively walks the concrete syntax tree. Upon finding a class declaration that Rindo
60356
+ * recognizes as a component, update the component class
60357
+ * @param node the current node in the tree being inspected
60358
+ * @returns the updated component class, or the unchanged node
60359
+ */
60142
60360
  const visitNode = (node) => {
60143
60361
  if (t.isClassDeclaration(node)) {
60144
60362
  const cmp = getComponentMeta(compilerCtx, tsSourceFile, node);
@@ -60163,7 +60381,11 @@ const nativeComponentTransform = (compilerCtx, transformOpts) => {
60163
60381
  if (moduleFile.isLegacy) {
60164
60382
  addLegacyApis(moduleFile);
60165
60383
  }
60166
- tsSourceFile = addImports(transformOpts, tsSourceFile, moduleFile.coreRuntimeApis, transformOpts.coreImportPath);
60384
+ const imports = [
60385
+ ...((_a = moduleFile === null || moduleFile === void 0 ? void 0 : moduleFile.coreRuntimeApis) !== null && _a !== void 0 ? _a : []),
60386
+ ...((_b = moduleFile === null || moduleFile === void 0 ? void 0 : moduleFile.outputTargetCoreRuntimeApis[DIST_CUSTOM_ELEMENTS]) !== null && _b !== void 0 ? _b : []),
60387
+ ];
60388
+ tsSourceFile = addImports(transformOpts, tsSourceFile, imports, transformOpts.coreImportPath);
60167
60389
  return tsSourceFile;
60168
60390
  };
60169
60391
  };
@@ -60380,6 +60602,14 @@ const updateBuildConditionals = (config, b) => {
60380
60602
  }
60381
60603
  };
60382
60604
 
60605
+ /**
60606
+ * Get build conditions appropriate for the `dist-custom-elements` Output
60607
+ * Target, including disabling lazy loading and hydration.
60608
+ *
60609
+ * @param config a validated user-supplied config
60610
+ * @param cmps metadata about the components currently being compiled
60611
+ * @returns build conditionals appropriate for the `dist-custom-elements` OT
60612
+ */
60383
60613
  const getCustomElementsBuildConditionals = (config, cmps) => {
60384
60614
  // because custom elements bundling does not customize the build conditionals by default
60385
60615
  // then the default in "import { BUILD, NAMESPACE } from '@rindo/core/internal/app-data'"
@@ -60414,9 +60644,9 @@ const outputCustomElements = async (config, compilerCtx, buildCtx) => {
60414
60644
  if (outputTargets.length === 0) {
60415
60645
  return;
60416
60646
  }
60417
- const bundlingEventMessage = 'generate custom elements';
60647
+ const bundlingEventMessage = `generate custom elements${config.sourceMap ? ' + source maps' : ''}`;
60418
60648
  const timespan = buildCtx.createTimeSpan(`${bundlingEventMessage} started`);
60419
- await Promise.all(outputTargets.map((target) => bundleCustomElements$1(config, compilerCtx, buildCtx, target)));
60649
+ await Promise.all(outputTargets.map((target) => bundleCustomElements(config, compilerCtx, buildCtx, target)));
60420
60650
  timespan.finish(`${bundlingEventMessage} finished`);
60421
60651
  };
60422
60652
  /**
@@ -60458,7 +60688,7 @@ const getBundleOptions = (config, buildCtx, compilerCtx, outputTarget) => ({
60458
60688
  * @param outputTarget the outputTarget we're currently dealing with
60459
60689
  * @returns an empty promise
60460
60690
  */
60461
- const bundleCustomElements$1 = async (config, compilerCtx, buildCtx, outputTarget) => {
60691
+ const bundleCustomElements = async (config, compilerCtx, buildCtx, outputTarget) => {
60462
60692
  try {
60463
60693
  const bundleOpts = getBundleOptions(config, buildCtx, compilerCtx, outputTarget);
60464
60694
  addCustomElementInputs(buildCtx, bundleOpts, outputTarget);
@@ -60564,7 +60794,7 @@ const addCustomElementInputs = (buildCtx, bundleOpts, outputTarget) => {
60564
60794
  bundleOpts.loader[coreKey] = exp.join('\n');
60565
60795
  });
60566
60796
  // Generate the contents of the entry file to be created by the bundler
60567
- bundleOpts.loader['\0core'] = generateEntryPoint$1(outputTarget, indexImports, indexExports, exportNames);
60797
+ bundleOpts.loader['\0core'] = generateEntryPoint(outputTarget, indexImports, indexExports, exportNames);
60568
60798
  };
60569
60799
  /**
60570
60800
  * Generate the entrypoint (`index.ts` file) contents for the `dist-custom-elements` output target
@@ -60574,7 +60804,7 @@ const addCustomElementInputs = (buildCtx, bundleOpts, outputTarget) => {
60574
60804
  * @param cmpNames The exported component names (could be aliased) from local component modules.
60575
60805
  * @returns the stringified contents to be placed in the entrypoint
60576
60806
  */
60577
- const generateEntryPoint$1 = (outputTarget, cmpImports = [], cmpExports = [], cmpNames = []) => {
60807
+ const generateEntryPoint = (outputTarget, cmpImports = [], cmpExports = [], cmpNames = []) => {
60578
60808
  const body = [];
60579
60809
  const imports = [];
60580
60810
  const exports = [];
@@ -60635,134 +60865,6 @@ const getCustomElementCustomTransformer = (config, compilerCtx, components, outp
60635
60865
  ];
60636
60866
  };
60637
60867
 
60638
- // TODO: fully delete dist-custom-elements-bundle code
60639
- const outputCustomElementsBundle = async (config, compilerCtx, buildCtx) => {
60640
- if (!config.buildDist) {
60641
- return;
60642
- }
60643
- const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElementsBundle);
60644
- if (outputTargets.length === 0) {
60645
- return;
60646
- }
60647
- const bundlingEventMessage = `generate custom elements bundle${config.sourceMap ? ' + source maps' : ''}`;
60648
- const timespan = buildCtx.createTimeSpan(`${bundlingEventMessage} started`);
60649
- await Promise.all(outputTargets.map((o) => bundleCustomElements(config, compilerCtx, buildCtx, o)));
60650
- timespan.finish(`${bundlingEventMessage} finished`);
60651
- };
60652
- const bundleCustomElements = async (config, compilerCtx, buildCtx, outputTarget) => {
60653
- try {
60654
- const bundleOpts = {
60655
- id: 'customElementsBundle',
60656
- platform: 'client',
60657
- conditionals: getCustomElementsBuildConditionals(config, buildCtx.components),
60658
- customTransformers: getCustomElementBundleCustomTransformer(config, compilerCtx),
60659
- externalRuntime: !!outputTarget.externalRuntime,
60660
- inlineWorkers: true,
60661
- inputs: {
60662
- index: '\0core',
60663
- },
60664
- loader: {
60665
- '\0core': generateEntryPoint(outputTarget, buildCtx),
60666
- },
60667
- preserveEntrySignatures: 'allow-extension',
60668
- };
60669
- const build = await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
60670
- if (build) {
60671
- const rollupOutput = await build.generate({
60672
- banner: generatePreamble(config),
60673
- format: 'esm',
60674
- sourcemap: config.sourceMap,
60675
- chunkFileNames: outputTarget.externalRuntime || !config.hashFileNames ? '[name].js' : 'p-[hash].js',
60676
- entryFileNames: '[name].js',
60677
- hoistTransitiveImports: false,
60678
- preferConst: true,
60679
- });
60680
- const minify = outputTarget.externalRuntime || outputTarget.minify !== true ? false : config.minifyJs;
60681
- const files = rollupOutput.output.map(async (bundle) => {
60682
- if (bundle.type === 'chunk') {
60683
- let code = bundle.code;
60684
- let sourceMap = rollupToRindoSourceMap(bundle.map);
60685
- const optimizeResults = await optimizeModule(config, compilerCtx, {
60686
- input: code,
60687
- isCore: bundle.isEntry,
60688
- minify,
60689
- sourceMap,
60690
- });
60691
- buildCtx.diagnostics.push(...optimizeResults.diagnostics);
60692
- if (!hasError(optimizeResults.diagnostics) && typeof optimizeResults.output === 'string') {
60693
- code = optimizeResults.output;
60694
- sourceMap = optimizeResults.sourceMap;
60695
- }
60696
- if (sourceMap) {
60697
- code = code + getSourceMappingUrlForEndOfFile(bundle.fileName);
60698
- await compilerCtx.fs.writeFile(join(outputTarget.dir, bundle.fileName + '.map'), JSON.stringify(sourceMap), {
60699
- outputTargetType: outputTarget.type,
60700
- });
60701
- }
60702
- await compilerCtx.fs.writeFile(join(outputTarget.dir, bundle.fileName), code, {
60703
- outputTargetType: outputTarget.type,
60704
- });
60705
- }
60706
- });
60707
- await Promise.all(files);
60708
- }
60709
- }
60710
- catch (e) {
60711
- catchError(buildCtx.diagnostics, e);
60712
- }
60713
- };
60714
- const generateEntryPoint = (outputTarget, buildCtx) => {
60715
- const imp = [];
60716
- const exp = [];
60717
- const exportNames = [];
60718
- imp.push(`import { proxyCustomElement } from '${RINDO_INTERNAL_CLIENT_ID}';`, `export { setAssetPath, setPlatformOptions } from '${RINDO_INTERNAL_CLIENT_ID}';`, `export * from '${USER_INDEX_ENTRY_ID}';`);
60719
- if (outputTarget.includeGlobalScripts !== false) {
60720
- imp.push(`import { globalScripts } from '${RINDO_APP_GLOBALS_ID}';`, `globalScripts();`);
60721
- }
60722
- buildCtx.components.forEach((cmp) => {
60723
- const exportName = dashToPascalCase$1(cmp.tagName);
60724
- const importName = cmp.componentClassName;
60725
- const importAs = `$Cmp${exportName}`;
60726
- if (cmp.isPlain) {
60727
- exp.push(`export { ${importName} as ${exportName} } from '${cmp.sourceFilePath}';`);
60728
- }
60729
- else {
60730
- const meta = stringifyRuntimeData(formatComponentRuntimeMeta(cmp, false));
60731
- imp.push(`import { ${importName} as ${importAs} } from '${cmp.sourceFilePath}';`);
60732
- exp.push(`export const ${exportName} = /*@__PURE__*/proxyCustomElement(${importAs}, ${meta});`);
60733
- }
60734
- exportNames.push(exportName);
60735
- });
60736
- exp.push(`export const defineCustomElements = (opts) => {`);
60737
- exp.push(` if (typeof customElements !== 'undefined') {`);
60738
- exp.push(` [`);
60739
- exp.push(` ${exportNames.join(',\n ')}`);
60740
- exp.push(` ].forEach(cmp => {`);
60741
- exp.push(` if (!customElements.get(cmp.is)) {`);
60742
- exp.push(` customElements.define(cmp.is, cmp, opts);`);
60743
- exp.push(` }`);
60744
- exp.push(` });`);
60745
- exp.push(` }`);
60746
- exp.push(`};`);
60747
- return [...imp, ...exp].join('\n') + '\n';
60748
- };
60749
- const getCustomElementBundleCustomTransformer = (config, compilerCtx) => {
60750
- const transformOpts = {
60751
- coreImportPath: RINDO_INTERNAL_CLIENT_ID,
60752
- componentExport: null,
60753
- componentMetadata: null,
60754
- currentDirectory: config.sys.getCurrentDirectory(),
60755
- proxy: null,
60756
- style: 'static',
60757
- styleImportData: 'queryparams',
60758
- };
60759
- return [
60760
- updateRindoCoreImports(transformOpts.coreImportPath),
60761
- nativeComponentTransform(compilerCtx, transformOpts),
60762
- removeCollectionImports(compilerCtx),
60763
- ];
60764
- };
60765
-
60766
60868
  const updateLazyComponentConstructor = (classMembers, moduleFile, cmp) => {
60767
60869
  const cstrMethodArgs = [
60768
60870
  t.factory.createParameterDeclaration(undefined, undefined, t.factory.createIdentifier(HOST_REF_ARG)),
@@ -63727,7 +63829,7 @@ export interface CustomElementsDefineOptions {
63727
63829
  export declare function defineCustomElements(win?: Window, opts?: CustomElementsDefineOptions): Promise<void>;
63728
63830
  export declare function applyPolyfills(): Promise<void>;
63729
63831
 
63730
- /**
63832
+ /**
63731
63833
  * Used to specify a nonce value that corresponds with an application's CSP.
63732
63834
  * When set, the nonce will be added to all dynamically created script and style tags at runtime.
63733
63835
  * Alternatively, the nonce value can be set on a meta tag in the DOM head
@@ -63748,7 +63850,7 @@ export declare function setNonce(nonce: string): void;
63748
63850
  */
63749
63851
  const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, typesDir) => {
63750
63852
  const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElements);
63751
- await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput$1(config, compilerCtx, buildCtx, typesDir, outputTarget)));
63853
+ await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, typesDir, outputTarget)));
63752
63854
  };
63753
63855
  /**
63754
63856
  * Generates types for a single `dist-custom-elements` output target definition in a Rindo project's configuration
@@ -63759,7 +63861,7 @@ const generateCustomElementsTypes = async (config, compilerCtx, buildCtx, typesD
63759
63861
  * @param typesDir path to the directory where type declarations are saved
63760
63862
  * @param outputTarget the output target for which types are being currently generated
63761
63863
  */
63762
- const generateCustomElementsTypesOutput$1 = async (config, compilerCtx, buildCtx, typesDir, outputTarget) => {
63864
+ const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, typesDir, outputTarget) => {
63763
63865
  const isBarrelExport = outputTarget.customElementsExportBehavior === 'single-export-module';
63764
63866
  const isBundleExport = outputTarget.customElementsExportBehavior === 'bundle';
63765
63867
  // the path where we're going to write the typedef for the whole dist-custom-elements output
@@ -63785,9 +63887,20 @@ const generateCustomElementsTypesOutput$1 = async (config, compilerCtx, buildCtx
63785
63887
  // - get the relative path to the component's source file from the source directory
63786
63888
  // - join that relative path to the relative path from the `index.d.ts` file to the
63787
63889
  // directory where typedefs are saved
63788
- const componentSourceRelPath = relative$1(config.srcDir, component.sourceFilePath).replace('.tsx', '');
63890
+ const componentSourceRelPath = relative$1(config.srcDir, component.sourceFilePath).replace(/\.tsx$/, '');
63789
63891
  const componentDTSPath = join(componentsTypeDirectoryRelPath, componentSourceRelPath);
63790
- return `export { ${importName} as ${exportName} } from '${componentDTSPath}';`;
63892
+ const defineFunctionExportName = `defineCustomElement${exportName}`;
63893
+ // Get the path to the sibling typedef file for the current component
63894
+ // When we bundle the code to generate the component JS files it generates
63895
+ // the JS and typedef files based on the component tag name. So, we can
63896
+ // just use the tagname to create the relative path
63897
+ const localComponentTypeDefFilePath = `./${component.tagName}`;
63898
+ return [
63899
+ `export { ${importName} as ${exportName} } from '${componentDTSPath}';`,
63900
+ // We need to alias each `defineCustomElement` function typedef to match the aliased name given to the
63901
+ // function in the `index.js`
63902
+ `export { defineCustomElement as ${defineFunctionExportName} } from '${localComponentTypeDefFilePath}';`,
63903
+ ].join('\n');
63791
63904
  }),
63792
63905
  ``,
63793
63906
  ]
@@ -63836,7 +63949,7 @@ const generateCustomElementsTypesOutput$1 = async (config, compilerCtx, buildCtx
63836
63949
  ]
63837
63950
  : []),
63838
63951
  ];
63839
- const componentsDtsRelPath = relDts$1(outputTarget.dir, join(typesDir, 'components.d.ts'));
63952
+ const componentsDtsRelPath = relDts(outputTarget.dir, join(typesDir, 'components.d.ts'));
63840
63953
  // To mirror the index.js file and only export the typedefs for the
63841
63954
  // entities exported there, we will re-export the typedefs iff
63842
63955
  // the `customElementsExportBehavior` is set to barrel component exports
@@ -63859,7 +63972,7 @@ const generateCustomElementsTypesOutput$1 = async (config, compilerCtx, buildCtx
63859
63972
  outputTargetType: outputTarget.type,
63860
63973
  });
63861
63974
  await Promise.all(components.map(async (cmp) => {
63862
- const dtsCode = generateCustomElementType$1(componentsDtsRelPath, cmp);
63975
+ const dtsCode = generateCustomElementType(componentsDtsRelPath, cmp);
63863
63976
  const fileName = `${cmp.tagName}.d.ts`;
63864
63977
  const filePath = join(outputTarget.dir, fileName);
63865
63978
  await compilerCtx.fs.writeFile(filePath, dtsCode, { outputTargetType: outputTarget.type });
@@ -63872,7 +63985,7 @@ const generateCustomElementsTypesOutput$1 = async (config, compilerCtx, buildCtx
63872
63985
  * @param cmp the component to generate the type declaration file for
63873
63986
  * @returns the contents of the type declaration file for the provided `cmp`
63874
63987
  */
63875
- const generateCustomElementType$1 = (componentsDtsRelPath, cmp) => {
63988
+ const generateCustomElementType = (componentsDtsRelPath, cmp) => {
63876
63989
  const tagNameAsPascal = dashToPascalCase$1(cmp.tagName);
63877
63990
  const o = [
63878
63991
  `import type { Components, JSX } from "${componentsDtsRelPath}";`,
@@ -63897,89 +64010,6 @@ const generateCustomElementType$1 = (componentsDtsRelPath, cmp) => {
63897
64010
  * @param dtsPath the destination path
63898
64011
  * @returns the relative path from the provided `fromPath` to the `dtsPath`
63899
64012
  */
63900
- const relDts$1 = (fromPath, dtsPath) => {
63901
- dtsPath = relative$1(fromPath, dtsPath);
63902
- if (!dtsPath.startsWith('.')) {
63903
- dtsPath = '.' + dtsPath;
63904
- }
63905
- return normalizePath$2(dtsPath.replace('.d.ts', ''));
63906
- };
63907
-
63908
- // TODO: fully delete dist-custom-elements-bundle code
63909
- const generateCustomElementsBundleTypes = async (config, compilerCtx, buildCtx, distDtsFilePath) => {
63910
- const outputTargets = config.outputTargets.filter(isOutputTargetDistCustomElementsBundle);
63911
- await Promise.all(outputTargets.map((outputTarget) => generateCustomElementsTypesOutput(config, compilerCtx, buildCtx, distDtsFilePath, outputTarget)));
63912
- };
63913
- const generateCustomElementsTypesOutput = async (config, compilerCtx, buildCtx, distDtsFilePath, outputTarget) => {
63914
- const customElementsDtsPath = join(outputTarget.dir, 'index.d.ts');
63915
- const componentsDtsRelPath = relDts(outputTarget.dir, distDtsFilePath);
63916
- const components = buildCtx.components.filter((m) => !m.isCollectionDependency);
63917
- const code = [
63918
- `/* ${config.namespace} custom elements bundle */`,
63919
- ``,
63920
- `import type { Components, JSX } from "${componentsDtsRelPath}";`,
63921
- ``,
63922
- ...components.map(generateCustomElementType),
63923
- `/**`,
63924
- ` * Utility to define all custom elements within this package using the tag name provided in the component's source. `,
63925
- ` * When defining each custom element, it will also check it's safe to define by:`,
63926
- ` *`,
63927
- ` * 1. Ensuring the "customElements" registry is available in the global context (window).`,
63928
- ` * 2. The component tag name is not already defined.`,
63929
- ` *`,
63930
- ` * Use the standard [customElements.define()](https://developer.mozilla.org/en-US/docs/Web/API/CustomElementRegistry/define) `,
63931
- ` * method instead to define custom elements individually, or to provide a different tag name.`,
63932
- ` */`,
63933
- `export declare const defineCustomElements: (opts?: any) => void;`,
63934
- ``,
63935
- `/**`,
63936
- ` * Used to manually set the base path where assets can be found.`,
63937
- ` * If the script is used as "module", it's recommended to use "import.meta.url",`,
63938
- ` * such as "setAssetPath(import.meta.url)". Other options include`,
63939
- ` * "setAssetPath(document.currentScript.src)", or using a bundler's replace plugin to`,
63940
- ` * dynamically set the path at build time, such as "setAssetPath(process.env.ASSET_PATH)".`,
63941
- ` * But do note that this configuration depends on how your script is bundled, or lack of`,
63942
- ` * bunding, and where your assets can be loaded from. Additionally custom bundling`,
63943
- ` * will have to ensure the static assets are copied to its build directory.`,
63944
- ` */`,
63945
- `export declare const setAssetPath: (path: string) => void;`,
63946
- ``,
63947
- `export interface SetPlatformOptions {`,
63948
- ` raf?: (c: FrameRequestCallback) => number;`,
63949
- ` ael?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;`,
63950
- ` rel?: (el: EventTarget, eventName: string, listener: EventListenerOrEventListenerObject, options: boolean | AddEventListenerOptions) => void;`,
63951
- ` ce?: (eventName: string, opts?: any) => CustomEvent;`,
63952
- `}`,
63953
- `export declare const setPlatformOptions: (opts: SetPlatformOptions) => void;`,
63954
- ``,
63955
- `export type { Components, JSX };`,
63956
- ``,
63957
- ];
63958
- const usersIndexJsPath = join(config.srcDir, 'index.ts');
63959
- const hasUserIndex = await compilerCtx.fs.access(usersIndexJsPath);
63960
- if (hasUserIndex) {
63961
- const userIndexRelPath = normalizePath$2(dirname(componentsDtsRelPath));
63962
- code.push(`export * from '${userIndexRelPath}';`);
63963
- }
63964
- else {
63965
- code.push(`export * from '${componentsDtsRelPath}';`);
63966
- }
63967
- await compilerCtx.fs.writeFile(customElementsDtsPath, code.join('\n') + `\n`, {
63968
- outputTargetType: outputTarget.type,
63969
- });
63970
- };
63971
- const generateCustomElementType = (cmp) => {
63972
- const tagNameAsPascal = dashToPascalCase$1(cmp.tagName);
63973
- const o = [
63974
- `interface ${tagNameAsPascal} extends Components.${tagNameAsPascal}, HTMLElement {}`,
63975
- `export const ${tagNameAsPascal}: {`,
63976
- ` prototype: ${tagNameAsPascal};`,
63977
- ` new (): ${tagNameAsPascal};`,
63978
- `};`,
63979
- ``,
63980
- ];
63981
- return o.join('\n');
63982
- };
63983
64013
  const relDts = (fromPath, dtsPath) => {
63984
64014
  dtsPath = relative$1(fromPath, dtsPath);
63985
64015
  if (!dtsPath.startsWith('.')) {
@@ -64538,7 +64568,6 @@ const generateTypesOutput = async (config, compilerCtx, buildCtx, outputTarget)
64538
64568
  await generateAppTypes(config, compilerCtx, buildCtx, distPath);
64539
64569
  const { typesDir } = outputTarget;
64540
64570
  if (distDtsFilePath) {
64541
- await generateCustomElementsBundleTypes(config, compilerCtx, buildCtx, distDtsFilePath);
64542
64571
  await generateCustomElementsTypes(config, compilerCtx, buildCtx, typesDir);
64543
64572
  }
64544
64573
  };
@@ -65104,7 +65133,6 @@ const generateOutputTargets = async (config, compilerCtx, buildCtx) => {
65104
65133
  outputCopy(config, compilerCtx, buildCtx),
65105
65134
  outputCollection(config, compilerCtx, buildCtx, changedModuleFiles),
65106
65135
  outputCustomElements(config, compilerCtx, buildCtx),
65107
- outputCustomElementsBundle(config, compilerCtx, buildCtx),
65108
65136
  outputHydrateScript(config, compilerCtx, buildCtx),
65109
65137
  outputLazyLoader(config, compilerCtx),
65110
65138
  outputLazy(config, compilerCtx, buildCtx),
@@ -65129,7 +65157,6 @@ const invalidateRollupCaches = (compilerCtx) => {
65129
65157
 
65130
65158
  const isEmptable = (o) => isOutputTargetDist(o) ||
65131
65159
  isOutputTargetDistCustomElements(o) ||
65132
- isOutputTargetDistCustomElementsBundle(o) ||
65133
65160
  isOutputTargetWww(o) ||
65134
65161
  isOutputTargetDistLazy(o) ||
65135
65162
  isOutputTargetDistLazyLoader(o) ||
@@ -69051,7 +69078,6 @@ const validateModule = async (config, compilerCtx, buildCtx) => {
69051
69078
  * value is supplied
69052
69079
  */
69053
69080
  function recommendedModulePath(config) {
69054
- const customElementsBundleOT = config.outputTargets.find(isOutputTargetDistCustomElementsBundle);
69055
69081
  const customElementsOT = config.outputTargets.find(isOutputTargetDistCustomElements);
69056
69082
  const distCollectionOT = config.outputTargets.find(isOutputTargetDistCollection);
69057
69083
  if (distCollectionOT) {
@@ -69061,10 +69087,6 @@ function recommendedModulePath(config) {
69061
69087
  const componentsIndexAbs = join(customElementsOT.dir, 'index.js');
69062
69088
  return relative$1(config.rootDir, componentsIndexAbs);
69063
69089
  }
69064
- if (customElementsBundleOT) {
69065
- const customElementsAbs = join(customElementsBundleOT.dir, 'index.js');
69066
- return relative$1(config.rootDir, customElementsAbs);
69067
- }
69068
69090
  // if no output target for which we define a recommended output target is set
69069
69091
  // we return `null`
69070
69092
  return null;
@@ -69633,6 +69655,12 @@ const createWatchBuild = async (config, compilerCtx) => {
69633
69655
  buildCtx.hasStyleChanges = hasStyleChanges(buildCtx);
69634
69656
  buildCtx.hasHtmlChanges = hasHtmlChanges(config, buildCtx);
69635
69657
  buildCtx.hasServiceWorkerChanges = hasServiceWorkerChanges(config, buildCtx);
69658
+ if (config.flags.debug) {
69659
+ config.logger.debug(`WATCH_BUILD::watchBuild::onBuild filesAdded: ${formatFilesForDebug(buildCtx.filesAdded)}`);
69660
+ config.logger.debug(`WATCH_BUILD::watchBuild::onBuild filesDeleted: ${formatFilesForDebug(buildCtx.filesDeleted)}`);
69661
+ config.logger.debug(`WATCH_BUILD::watchBuild::onBuild filesUpdated: ${formatFilesForDebug(buildCtx.filesUpdated)}`);
69662
+ config.logger.debug(`WATCH_BUILD::watchBuild::onBuild filesWritten: ${formatFilesForDebug(buildCtx.filesWritten)}`);
69663
+ }
69636
69664
  dirsAdded.clear();
69637
69665
  dirsDeleted.clear();
69638
69666
  filesAdded.clear();
@@ -69645,6 +69673,21 @@ const createWatchBuild = async (config, compilerCtx) => {
69645
69673
  isRebuild = true;
69646
69674
  }
69647
69675
  };
69676
+ /**
69677
+ * Utility method for formatting a debug message that must either list a number of files, or the word 'none' if the
69678
+ * provided list is empty
69679
+ * @param files a list of files, the list may be empty
69680
+ * @returns the provided list if it is not empty. otherwise, return the word 'none'
69681
+ */
69682
+ const formatFilesForDebug = (files) => {
69683
+ /**
69684
+ * In the created message, it's important that there's no whitespace prior to the file name.
69685
+ * Rindo's logger will split messages by whitespace according to the width of the terminal window.
69686
+ * Since file names can be fully qualified paths (and therefore quite long), putting whitespace between a '-' and
69687
+ * the path can lead to formatted messages where the '-' is on its own line
69688
+ */
69689
+ return files.length > 0 ? files.map((filename) => `-${filename}`).join('\n') : 'none';
69690
+ };
69648
69691
  const start = async () => {
69649
69692
  const srcRead = watchSrcDirectory(config, compilerCtx);
69650
69693
  const otherRead = watchRootFiles(config, compilerCtx);
@@ -69675,7 +69718,7 @@ const createWatchBuild = async (config, compilerCtx) => {
69675
69718
  filesDeleted.add(p);
69676
69719
  break;
69677
69720
  }
69678
- config.logger.debug(`onFsChange ${eventKind}: ${p}`);
69721
+ config.logger.debug(`WATCH_BUILD::fs_event_change - type=${eventKind}, path=${p}, time=${new Date().getTime()}`);
69679
69722
  tsWatchProgram.rebuild();
69680
69723
  }
69681
69724
  };
@@ -71447,32 +71490,6 @@ const validateCustomElement = (config, userOutputs) => {
71447
71490
  }, []);
71448
71491
  };
71449
71492
 
71450
- // TODO: fully delete dist-custom-elements-bundle code
71451
- const validateCustomElementBundle = (config, userOutputs) => {
71452
- return userOutputs.filter(isOutputTargetDistCustomElementsBundle).reduce((arr, o) => {
71453
- const outputTarget = {
71454
- ...o,
71455
- dir: getAbsolutePath(config, o.dir || 'dist/custom-elements'),
71456
- };
71457
- if (!isBoolean$1(outputTarget.empty)) {
71458
- outputTarget.empty = true;
71459
- }
71460
- if (!isBoolean$1(outputTarget.externalRuntime)) {
71461
- outputTarget.externalRuntime = true;
71462
- }
71463
- outputTarget.copy = validateCopy(outputTarget.copy, []);
71464
- if (outputTarget.copy.length > 0) {
71465
- arr.push({
71466
- type: COPY,
71467
- dir: config.rootDir,
71468
- copy: [...outputTarget.copy],
71469
- });
71470
- }
71471
- arr.push(outputTarget);
71472
- return arr;
71473
- }, []);
71474
- };
71475
-
71476
71493
  const validateCustomOutput = (config, diagnostics, userOutputs) => {
71477
71494
  return userOutputs.filter(isOutputTargetCustom).map((o) => {
71478
71495
  if (o.validate) {
@@ -71974,7 +71991,6 @@ const validateOutputTargets = (config, diagnostics) => {
71974
71991
  config.outputTargets = [
71975
71992
  ...validateCollection(config, userOutputs),
71976
71993
  ...validateCustomElement(config, userOutputs),
71977
- ...validateCustomElementBundle(config, userOutputs),
71978
71994
  ...validateCustomOutput(config, diagnostics, userOutputs),
71979
71995
  ...validateLazy(config, userOutputs),
71980
71996
  ...validateWww(config, diagnostics, userOutputs),