@knapsack/renderer-react 4.69.13 → 4.69.14--canary.4821.246c5f4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -17,7 +17,8 @@ var __dirname = /* @__PURE__ */ getDirname();
17
17
  // src/renderer-react.ts
18
18
  import sleep from "sleep-promise";
19
19
  import {
20
- RendererWebpackBase
20
+ RendererWebpackBase,
21
+ convertImportMapToNeededImportsByPath
21
22
  } from "@knapsack/renderer-webpack-base";
22
23
  import { pascalCase, isFirstLetterCapital } from "@knapsack/utils";
23
24
  import { knapsackEvents, log as log2 } from "@knapsack/app";
@@ -33,9 +34,10 @@ import {
33
34
  findUpPkgJson,
34
35
  getJsExportNames as getJsExportNames2,
35
36
  readFile as readFile2,
36
- formatCode as formatCode2
37
+ formatCode as formatCode2,
38
+ assertFileExists
37
39
  } from "@knapsack/file-utils";
38
- import { join, relative, parse } from "path";
40
+ import { join, relative, parse, isAbsolute } from "path";
39
41
 
40
42
  // src/utils.ts
41
43
  import { log } from "@knapsack/app";
@@ -733,6 +735,7 @@ var rendererMetaScriptTagId = "ks-react-meta";
733
735
  // src/renderer-react.ts
734
736
  var { pkg } = findUpPkgJson(__dirname);
735
737
  log2.setupUpdateNotifier({ ...pkg, name: pkg.name, version: pkg.version });
738
+ var errorCatcherPath = join(__dirname, "./error-catcher.mjs");
736
739
  var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpackBase {
737
740
  static {
738
741
  __name(this, "KnapsackReactRenderer");
@@ -752,22 +755,29 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
752
755
  } = {}) {
753
756
  super({
754
757
  id,
755
- extension: ".jsx",
756
758
  language: "jsx",
757
759
  webpackConfig,
758
760
  extraScripts: [
759
761
  // this is the code in `./client/init.mts`
760
762
  "@knapsack/renderer-react/client"
761
- ]
763
+ ],
764
+ codeSrcs: [demoWrapperPath, errorCatcherPath]
762
765
  });
763
766
  this.language = "jsx";
764
767
  this.assets = [];
765
- this.demoWrapperPath = demoWrapperPath;
768
+ this.demoWrapperPath = isAbsolute(demoWrapperPath) ? demoWrapperPath : this.resolvePathSync({
769
+ path: demoWrapperPath,
770
+ resolveFromDir: this.userConfigDir
771
+ }).absolutePath;
772
+ assertFileExists(
773
+ this.demoWrapperPath,
774
+ `Could not find demo wrapper at: "${this.demoWrapperPath}"
775
+ Please adjust setting in "knapsack.config.js" or pass a different path when creating the React Renderer.`
776
+ );
766
777
  this.disableReactStrictMode = disableReactStrictMode;
767
778
  this.creators = [createReactPattern];
768
779
  }
769
- init = /* @__PURE__ */ __name(async (opt) => {
770
- await super.init(opt);
780
+ init = /* @__PURE__ */ __name(async () => {
771
781
  this.assets = await copyReactAssets(this.outputDir, this.publicPath);
772
782
  if (!await fileExists(this.demoWrapperPath)) {
773
783
  throw new Error(
@@ -813,76 +823,37 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
813
823
  };
814
824
  return config;
815
825
  }, "createWebpackConfig");
816
- getJsImports = /* @__PURE__ */ __name(() => {
817
- const imports = super.getJsImports();
818
- imports.push(
819
- {
820
- type: "extra",
821
- importInfo: {
822
- type: "default",
823
- path: this.demoWrapperPath,
824
- name: "DemoWrapper"
825
- }
826
- },
827
- {
828
- type: "extra",
829
- importInfo: {
830
- type: "default",
831
- path: join(__dirname, "./error-catcher.mjs"),
832
- name: "ErrorCatcher"
833
- }
834
- }
835
- );
836
- return imports;
837
- }, "getJsImports");
838
826
  async prepClientRenderResults({
839
827
  usage,
840
828
  demoApp,
841
- imports: xImports,
842
- renderOptions: { pattern, template, demo }
829
+ importMap,
830
+ renderOptions: { demo, state, patternId, templateId }
843
831
  }) {
844
- const extraImports = this.getJsImports().filter(
845
- (imp) => imp.type === "extra"
846
- );
847
- const { imports, isDeclaredVarsUnique, nameCollisions } = this.makeKsJsImportsUnique({ imports: [...xImports, ...extraImports] });
848
- if (!isDeclaredVarsUnique) {
849
- log2.error(`${nameCollisions.join(", ")} are declared multiple times`, {
850
- imports
851
- });
852
- }
853
832
  const meta = {
854
833
  demo,
855
834
  disableReactStrictMode: this.disableReactStrictMode,
856
- neededImports: imports,
835
+ neededImportsByPath: convertImportMapToNeededImportsByPath(importMap),
836
+ extraImports: {
837
+ DemoWrapper: {
838
+ type: "default",
839
+ path: this.demoWrapperPath,
840
+ name: "DemoWrapper"
841
+ },
842
+ ErrorCatcher: {
843
+ type: "default",
844
+ path: errorCatcherPath,
845
+ name: "ErrorCatcher"
846
+ }
847
+ },
857
848
  demoWrapperProps: {
858
- pattern,
859
- template,
860
- demo,
861
- patternsUsed: imports.flatMap((imp) => {
862
- if (imp.type === "pattern-template") {
863
- return [
864
- {
865
- patternId: imp.patternId,
866
- templateId: imp.templateId
867
- }
868
- ];
869
- }
870
- if (imp.type === "pattern-template-demo") {
871
- return [
872
- {
873
- patternId: imp.patternId,
874
- templateId: imp.templateId,
875
- demoId: imp.demoId
876
- }
877
- ];
878
- }
879
- return [];
880
- })
849
+ patternId,
850
+ templateId,
851
+ demo
881
852
  }
882
853
  };
883
854
  let code = `
884
855
  window.knapsack = window.knapsack || {};
885
- window.knapsack.getDemoApp = ({ ${imports.map((i) => i.importInfo.name).join(", ")} }) => {
856
+ window.knapsack.getDemoApp = ({ ${[...importMap.keys()].join(", ")} }) => {
886
857
  ${demoApp}
887
858
  return ${demoAppName}
888
859
  }
@@ -904,7 +875,7 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
904
875
  <script type="application/javascript">${code}</script>
905
876
  <div id="render-root" class="knapsack-pattern-direct-parent" data-dev-note="Knapsack React Template Wrapper"></div>
906
877
  ${this.assets.map((asset) => `<script src="${asset}"></script>`).join("\n")}
907
- ${this.createHtmlTagsForAssetPaths({
878
+ ${RendererWebpackBase.createHtmlTagsForAssetPaths({
908
879
  assets: this.getWebpackAssetPaths(),
909
880
  // we need the scripts to finish adding methods to the global knapsack object synchronously before the client-side code runs that is in the <script> tag below
910
881
  scriptTagsAreAsync: false
@@ -948,9 +919,12 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
948
919
  await sleep(waitTime);
949
920
  }
950
921
  }
951
- const [templateFileContents, { usage, imports }] = await Promise.all([
922
+ const [templateFileContents, { usage, importMap }] = await Promise.all([
952
923
  readFile2(templateDemoPath),
953
- this.getUsageAndImports(opt)
924
+ this.getUsageAndImports({
925
+ ...opt,
926
+ importMap: /* @__PURE__ */ new Map()
927
+ })
954
928
  ]);
955
929
  const demoApp = await getDemoAppUsage({
956
930
  children: usage
@@ -958,15 +932,18 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
958
932
  const results = await this.prepClientRenderResults({
959
933
  usage: templateFileContents,
960
934
  demoApp,
961
- imports,
962
- renderOptions: opt
935
+ renderOptions: opt,
936
+ importMap
963
937
  });
964
938
  return results;
965
939
  }
966
940
  if (opt.demo?.type === "data") {
967
- const { usage, imports } = await this.getUsageAndImports(opt);
968
- const { code: importCode } = this.createJsImportCodeBlock({
969
- imports
941
+ const { usage, importMap } = await this.getUsageAndImports({
942
+ ...opt,
943
+ importMap: /* @__PURE__ */ new Map()
944
+ });
945
+ const importCode = RendererWebpackBase.createJsImportCodeBlock({
946
+ importMap
970
947
  });
971
948
  const [demoAppUsage, demoApp] = await Promise.all([
972
949
  getDemoAppUsage({
@@ -981,32 +958,40 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
981
958
  return this.prepClientRenderResults({
982
959
  demoApp,
983
960
  usage: demoAppUsage,
984
- imports,
985
- renderOptions: opt
961
+ renderOptions: opt,
962
+ importMap
986
963
  });
987
964
  }
988
965
  }, "render");
989
966
  getUsageAndImports = /* @__PURE__ */ __name(async ({
990
- pattern,
991
- template,
992
- patternManifest,
993
- demo
967
+ patternId,
968
+ templateId,
969
+ demo,
970
+ state,
971
+ importMap
994
972
  }) => {
995
- if (demo?.type && demo.type === "data") {
973
+ if (!demo) {
974
+ throw new Error(
975
+ `No demo provided while rendering ${patternId} ${templateId}`
976
+ );
977
+ }
978
+ const pattern = state.patterns[patternId];
979
+ if (!pattern) {
980
+ throw new Error(`Could not find pattern: ${patternId}`);
981
+ }
982
+ if (demo.type === "data") {
983
+ const template = pattern.templates.find((t) => t.id === templateId);
984
+ if (!template) {
985
+ throw new Error(`Could not find template: ${templateId}`);
986
+ }
996
987
  const {
997
988
  data: { props, slots, slotsOptionsComputed }
998
989
  } = demo;
999
- const importInfo = this.getJsImport({
1000
- patternId: pattern.id,
1001
- templateId: template.id
990
+ const { name: templateName } = await this.addUniqueValueToImportMap({
991
+ importMap,
992
+ path: template.path,
993
+ alias: template.alias || "default"
1002
994
  });
1003
- if (!importInfo) {
1004
- throw new Error(
1005
- `Could not find import for pattern-template: ${pattern.id}-${template.id}`
1006
- );
1007
- }
1008
- const { type, name: templateName } = importInfo.importInfo;
1009
- const importInfos = [importInfo];
1010
995
  const children = [];
1011
996
  const extraProps = [];
1012
997
  if (slots) {
@@ -1016,6 +1001,7 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
1016
1001
  const slotItems = slots[slotName];
1017
1002
  const slotItemsUsages = await Promise.all(
1018
1003
  slotItems.filter((slotItem) => {
1004
+ if (!slotItem) return false;
1019
1005
  if (slotItem.type !== "text") {
1020
1006
  if (!slotItem.patternId) return false;
1021
1007
  if (!slotItem.templateId) return false;
@@ -1031,31 +1017,39 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
1031
1017
  }
1032
1018
  return slotItem.text;
1033
1019
  }
1034
- const slotPattern = patternManifest.getPattern(
1035
- slotItem.patternId
1036
- );
1037
- const slotTemplate = slotPattern.templates.find(
1038
- (t) => t.id === slotItem.templateId
1039
- );
1040
1020
  if (slotItem.type === "template-reference") {
1041
- const { usage: usage2, imports } = await this.getUsageAndImports({
1042
- pattern: slotPattern,
1043
- template: slotTemplate,
1044
- patternManifest
1021
+ const slottedTemplate = state.patterns[slotItem.patternId]?.templates.find((t) => t.id === slotItem.templateId);
1022
+ if (!slottedTemplate) {
1023
+ throw new Error(
1024
+ `Could not find slotted template: ${slotItem.patternId} ${slotItem.templateId}`
1025
+ );
1026
+ }
1027
+ const templateRefImport = await this.addUniqueValueToImportMap({
1028
+ importMap,
1029
+ path: slottedTemplate.path,
1030
+ alias: slottedTemplate.alias || "default"
1045
1031
  });
1046
- importInfos.push(...imports);
1047
- return usage2;
1032
+ return templateRefImport.name;
1048
1033
  }
1049
1034
  if (slotItem.type === "template-demo") {
1050
- const { usage: usage2, imports } = await this.getUsageAndImports({
1051
- pattern: slotPattern,
1052
- template: slotTemplate,
1053
- demo: slotItem.demo || this.patterns.demosById[slotItem.demoId],
1054
- patternManifest
1035
+ const thisDemo = slotItem.demo;
1036
+ if (!thisDemo) {
1037
+ throw new Error(
1038
+ `Could not find slotted template demo ${JSON.stringify(
1039
+ slotItem
1040
+ )}`
1041
+ );
1042
+ }
1043
+ const { usage: usage2 } = await this.getUsageAndImports({
1044
+ patternId: thisDemo.patternId,
1045
+ templateId: thisDemo.templateId,
1046
+ demo: thisDemo,
1047
+ state,
1048
+ importMap
1055
1049
  });
1056
- importInfos.push(...imports);
1057
1050
  return usage2;
1058
1051
  }
1052
+ const _exhaustiveCheck2 = slotItem;
1059
1053
  throw new Error(
1060
1054
  `Unknown slot item: ${JSON.stringify(slotItem)}`
1061
1055
  );
@@ -1114,50 +1108,25 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
1114
1108
  });
1115
1109
  return {
1116
1110
  usage,
1117
- imports: importInfos
1111
+ importMap
1118
1112
  };
1119
1113
  }
1120
- if (demo?.type && demo.type === "template") {
1121
- const importInfo = this.getJsImport({
1122
- patternId: pattern.id,
1123
- templateId: template.id,
1124
- demoId: demo.id
1114
+ if (demo.type === "template") {
1115
+ const { templateInfo } = demo;
1116
+ const { name: templateName } = await this.addUniqueValueToImportMap({
1117
+ importMap,
1118
+ path: templateInfo.path,
1119
+ alias: templateInfo.alias || "default"
1125
1120
  });
1126
- if (!importInfo) {
1127
- throw new Error(
1128
- `Could not find import for pattern-template-demo: ${pattern.id}-${template.id}-${demo.id}`
1129
- );
1130
- }
1131
- const { type, name: templateName } = importInfo.importInfo;
1132
1121
  const usage = await getUsage({ templateName });
1133
1122
  return {
1134
1123
  usage,
1135
- imports: [importInfo]
1136
- };
1137
- }
1138
- if (!demo) {
1139
- const importInfo = this.getJsImport({
1140
- patternId: pattern.id,
1141
- templateId: template.id
1142
- });
1143
- if (!importInfo) {
1144
- throw new Error(
1145
- `Could not find import for pattern-template: ${pattern.id}-${template.id}`
1146
- );
1147
- }
1148
- const { type, name: templateName } = importInfo.importInfo;
1149
- return {
1150
- /**
1151
- * i.e. Given a React Component, `Button`, normally this would be `<Button>` with a demo, but since there is none this will just be a reference to it: `Button`
1152
- * @see {KsSlotInfo['isTemplateReference']}
1153
- * @see {SlottedTemplate}
1154
- */
1155
- usage: templateName,
1156
- imports: [importInfo]
1124
+ importMap
1157
1125
  };
1158
1126
  }
1127
+ const _exhaustiveCheck = demo;
1159
1128
  throw new Error(
1160
- `Unhandled demo type for ${pattern.id}-${template.id}: ${JSON.stringify(
1129
+ `Unhandled demo type for ${patternId}-${templateId}: ${JSON.stringify(
1161
1130
  demo
1162
1131
  )}`
1163
1132
  );
@@ -1180,8 +1149,8 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
1180
1149
  }
1181
1150
  return spec;
1182
1151
  }, "inferSpec");
1183
- watch = /* @__PURE__ */ __name(async (opt) => {
1184
- super.watch(opt);
1152
+ watch = /* @__PURE__ */ __name(async () => {
1153
+ super.watch();
1185
1154
  knapsackEvents.onPatternTemplateChanged(() => {
1186
1155
  clearInferSpecCache();
1187
1156
  });
@@ -1259,21 +1228,34 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
1259
1228
  ];
1260
1229
  }, "alterTemplateMetaFiles");
1261
1230
  getTemplateSuggestions = /* @__PURE__ */ __name(async ({
1262
- newPath
1231
+ newPath,
1232
+ state
1263
1233
  }) => {
1264
- const { data: dataDir } = this.patterns.userConfig;
1265
- const { allTemplateDemos, allTemplates } = this.getMyTemplates();
1266
- const usedSuggestions = [
1267
- ...allTemplateDemos,
1268
- ...allTemplates
1269
- ].map(({ path: path3, alias }) => {
1270
- return {
1271
- path: path3,
1272
- alias: alias || "default"
1273
- };
1274
- });
1234
+ const usedSuggestions = Object.values(state.patterns).reduce(
1235
+ (acc, { templateDemos, templates }) => {
1236
+ templates.forEach(({ path: path3, alias, templateLanguageId }) => {
1237
+ if (templateLanguageId !== this.id) return;
1238
+ acc.push({ path: path3, alias });
1239
+ });
1240
+ templateDemos.forEach(
1241
+ ({ templateInfo: { path: path3, alias }, templateLanguageId }) => {
1242
+ if (templateLanguageId !== this.id) return;
1243
+ acc.push({ path: path3, alias });
1244
+ }
1245
+ );
1246
+ return acc;
1247
+ },
1248
+ []
1249
+ );
1250
+ const codeSrcs = new Set(this.getCodeSrcs());
1251
+ codeSrcs.delete(this.demoWrapperPath);
1252
+ codeSrcs.delete(errorCatcherPath);
1275
1253
  const allPaths = [
1276
- .../* @__PURE__ */ new Set([newPath, ...usedSuggestions.map(({ path: path3 }) => path3)])
1254
+ .../* @__PURE__ */ new Set([
1255
+ newPath,
1256
+ ...Object.keys(this.pkgPathAliases || {}),
1257
+ ...codeSrcs
1258
+ ])
1277
1259
  ];
1278
1260
  const allSuggestions = await Promise.all(
1279
1261
  allPaths.map(async (path3) => {
@@ -1281,7 +1263,7 @@ var KnapsackReactRenderer = class _KnapsackReactRenderer extends RendererWebpack
1281
1263
  try {
1282
1264
  const { exports, errorMsg } = await getJsExportNames2({
1283
1265
  path: path3,
1284
- resolveFromDir: dataDir,
1266
+ resolveFromDir: this.dataDir,
1285
1267
  pkgPathAliases: this.pkgPathAliases
1286
1268
  });
1287
1269
  if (errorMsg) {