@fairfox/polly 0.11.0 → 0.12.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.
Files changed (40) hide show
  1. package/dist/src/client/index.d.ts +33 -0
  2. package/dist/src/client/index.js +586 -0
  3. package/dist/src/client/index.js.map +13 -0
  4. package/dist/src/client/wrapper.d.ts +54 -0
  5. package/dist/src/core/clock.d.ts +63 -0
  6. package/dist/src/elysia/index.d.ts +43 -0
  7. package/dist/src/elysia/index.js +241 -0
  8. package/dist/src/elysia/index.js.map +12 -0
  9. package/dist/src/elysia/plugin.d.ts +85 -0
  10. package/dist/src/elysia/tla-generator.d.ts +16 -0
  11. package/dist/src/elysia/types.d.ts +137 -0
  12. package/dist/src/utils/function-serialization.d.ts +14 -0
  13. package/dist/tools/analysis/src/extract/adr.d.ts +37 -0
  14. package/dist/tools/analysis/src/extract/architecture.d.ts +42 -0
  15. package/dist/tools/analysis/src/extract/contexts.d.ts +74 -0
  16. package/dist/tools/analysis/src/extract/flows.d.ts +68 -0
  17. package/dist/tools/analysis/src/extract/handlers.d.ts +330 -0
  18. package/dist/tools/analysis/src/extract/index.d.ts +9 -0
  19. package/dist/tools/analysis/src/extract/integrations.d.ts +77 -0
  20. package/dist/tools/analysis/src/extract/manifest.d.ts +64 -0
  21. package/dist/tools/analysis/src/extract/project-detector.d.ts +103 -0
  22. package/dist/tools/analysis/src/extract/relationships.d.ts +119 -0
  23. package/dist/tools/analysis/src/extract/types.d.ts +139 -0
  24. package/dist/tools/analysis/src/index.d.ts +2 -0
  25. package/dist/tools/analysis/src/types/adr.d.ts +39 -0
  26. package/dist/tools/analysis/src/types/architecture.d.ts +198 -0
  27. package/dist/tools/analysis/src/types/core.d.ts +178 -0
  28. package/dist/tools/analysis/src/types/index.d.ts +4 -0
  29. package/dist/tools/teach/src/cli.js +140 -69
  30. package/dist/tools/teach/src/cli.js.map +12 -12
  31. package/dist/tools/teach/src/index.d.ts +28 -0
  32. package/dist/tools/teach/src/index.js +145 -72
  33. package/dist/tools/teach/src/index.js.map +13 -13
  34. package/dist/tools/verify/src/cli.js +33 -11
  35. package/dist/tools/verify/src/cli.js.map +5 -5
  36. package/dist/tools/visualize/src/cli.js +125 -66
  37. package/dist/tools/visualize/src/cli.js.map +11 -11
  38. package/dist/tools/visualize/src/codegen/structurizr.d.ts +343 -0
  39. package/dist/tools/visualize/src/types/structurizr.d.ts +235 -0
  40. package/package.json +10 -5
@@ -0,0 +1,28 @@
1
+ import type { ArchitectureAnalysis } from "../../analysis/src/types/architecture.ts";
2
+ export interface TeachingMaterial {
3
+ analysis: ArchitectureAnalysis;
4
+ visualization: string;
5
+ formattedOutput: string;
6
+ }
7
+ export interface TeachOptions {
8
+ projectRoot: string;
9
+ tsConfigPath?: string;
10
+ }
11
+ /**
12
+ * Generate teaching material for a Polly project
13
+ *
14
+ * @param options Configuration options
15
+ * @returns Teaching material including analysis, visualization, and formatted output
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * import { generateTeachingMaterial } from '@fairfox/polly/teach'
20
+ *
21
+ * const material = await generateTeachingMaterial({
22
+ * projectRoot: process.cwd()
23
+ * })
24
+ *
25
+ * console.log(material.formattedOutput)
26
+ * ```
27
+ */
28
+ export declare function generateTeachingMaterial(options: TeachOptions): Promise<TeachingMaterial>;
@@ -235845,9 +235845,12 @@ class ContextAnalyzer {
235845
235845
  const leadingComments = firstStatement.getLeadingCommentRanges();
235846
235846
  if (leadingComments.length === 0)
235847
235847
  return;
235848
- const comment = leadingComments[0].getText();
235848
+ const firstComment = leadingComments[0];
235849
+ if (!firstComment)
235850
+ return;
235851
+ const comment = firstComment.getText();
235849
235852
  const descMatch = comment.match(/@description\s+(.+?)(?:\n|$)/s);
235850
- if (descMatch) {
235853
+ if (descMatch?.[1]) {
235851
235854
  return descMatch[1].trim();
235852
235855
  }
235853
235856
  const lines = comment.split(`
@@ -235946,6 +235949,8 @@ class ContextAnalyzer {
235946
235949
  if (params.length === 0)
235947
235950
  return [];
235948
235951
  const propsParam = params[0];
235952
+ if (!propsParam)
235953
+ return [];
235949
235954
  const type2 = propsParam.getType();
235950
235955
  const props = [];
235951
235956
  for (const prop of type2.getProperties()) {
@@ -235961,6 +235966,8 @@ class ContextAnalyzer {
235961
235966
  if (typeArgs.length === 0)
235962
235967
  return [];
235963
235968
  const propsType = typeArgs[0];
235969
+ if (!propsType)
235970
+ return [];
235964
235971
  const props = [];
235965
235972
  for (const prop of propsType.getProperties()) {
235966
235973
  props.push(prop.getName());
@@ -235968,10 +235975,15 @@ class ContextAnalyzer {
235968
235975
  return props;
235969
235976
  }
235970
235977
  extractJSDocDescription(node) {
235978
+ if (!import_ts_morph.Node.isJSDocable(node))
235979
+ return;
235971
235980
  const jsDocs = node.getJsDocs();
235972
235981
  if (jsDocs.length === 0)
235973
235982
  return;
235974
- const description = jsDocs[0].getDescription().trim();
235983
+ const firstDoc = jsDocs[0];
235984
+ if (!firstDoc)
235985
+ return;
235986
+ const description = firstDoc.getDescription().trim();
235975
235987
  return description || undefined;
235976
235988
  }
235977
235989
  isUIContext(contextType) {
@@ -236055,7 +236067,10 @@ class FlowAnalyzer {
236055
236067
  if (args.length === 0) {
236056
236068
  return;
236057
236069
  }
236058
- const msgType = this.extractMessageTypeFromArg(args[0]);
236070
+ const firstArg = args[0];
236071
+ if (!firstArg)
236072
+ return;
236073
+ const msgType = this.extractMessageTypeFromArg(firstArg);
236059
236074
  if (msgType === messageType) {
236060
236075
  senders.push({
236061
236076
  context,
@@ -236075,7 +236090,10 @@ class FlowAnalyzer {
236075
236090
  if (args.length === 0) {
236076
236091
  return;
236077
236092
  }
236078
- const msgType = this.extractMessageTypeFromArg(args[0]);
236093
+ const firstArg = args[0];
236094
+ if (!firstArg)
236095
+ return;
236096
+ const msgType = this.extractMessageTypeFromArg(firstArg);
236079
236097
  if (msgType === messageType) {
236080
236098
  senders.push({
236081
236099
  context,
@@ -236145,7 +236163,10 @@ class FlowAnalyzer {
236145
236163
  if (args.length === 0) {
236146
236164
  return;
236147
236165
  }
236148
- const messageType = this.extractMessageTypeFromArg(args[0]);
236166
+ const firstArg = args[0];
236167
+ if (!firstArg)
236168
+ return;
236169
+ const messageType = this.extractMessageTypeFromArg(firstArg);
236149
236170
  if (messageType) {
236150
236171
  sends.push({
236151
236172
  messageType,
@@ -236198,10 +236219,17 @@ class FlowAnalyzer {
236198
236219
  });
236199
236220
  if (!targetNode)
236200
236221
  return {};
236201
- const jsDocs = targetNode.getJsDocs?.() || [];
236222
+ const nodeAny = targetNode;
236223
+ if (!("getJsDocs" in nodeAny) || typeof nodeAny.getJsDocs !== "function") {
236224
+ return {};
236225
+ }
236226
+ const jsDocs = nodeAny.getJsDocs();
236202
236227
  if (jsDocs.length === 0)
236203
236228
  return {};
236204
- const comment = jsDocs[0].getText();
236229
+ const firstDoc = jsDocs[0];
236230
+ if (!firstDoc)
236231
+ return {};
236232
+ const comment = firstDoc.getText();
236205
236233
  const flowMatch = comment.match(/@flow\s+([^\s]+)/);
236206
236234
  const flowName = flowMatch ? flowMatch[1] : undefined;
236207
236235
  const triggerMatch = comment.match(/@trigger\s+(.+?)(?:\n|$)/);
@@ -237001,7 +237029,10 @@ class HandlerExtractor {
237001
237029
  if (!body) {
237002
237030
  return;
237003
237031
  }
237004
- const firstAwaitPos = awaitExpressions[0].getStart();
237032
+ const firstAwait = awaitExpressions[0];
237033
+ if (!firstAwait)
237034
+ return;
237035
+ const firstAwaitPos = firstAwait.getStart();
237005
237036
  funcNode.forEachDescendant((node) => {
237006
237037
  if (import_ts_morph4.Node.isBinaryExpression(node)) {
237007
237038
  this.checkBinaryExpressionMutation(node, firstAwaitPos, mutations);
@@ -237052,6 +237083,8 @@ class HandlerExtractor {
237052
237083
  return null;
237053
237084
  }
237054
237085
  const conditionArg = args[0];
237086
+ if (!conditionArg)
237087
+ return null;
237055
237088
  const expression = conditionArg.getText();
237056
237089
  let message;
237057
237090
  if (args.length >= 2 && import_ts_morph4.Node.isStringLiteral(args[1])) {
@@ -237357,12 +237390,17 @@ class HandlerExtractor {
237357
237390
  return;
237358
237391
  }
237359
237392
  extractMessageTypeFromTypePredicateFunction(node, returnTypeNode) {
237360
- const typeNode = returnTypeNode.getTypeNode();
237361
- if (typeNode) {
237362
- const typeName = typeNode.getText();
237363
- const messageType = this.extractMessageTypeFromTypeName(typeName);
237364
- if (messageType) {
237365
- return messageType;
237393
+ if (!import_ts_morph4.Node.isTypePredicate(returnTypeNode)) {
237394
+ return null;
237395
+ }
237396
+ if ("getTypeNode" in returnTypeNode && typeof returnTypeNode.getTypeNode === "function") {
237397
+ const typeNode = returnTypeNode.getTypeNode();
237398
+ if (typeNode) {
237399
+ const typeName = typeNode.getText();
237400
+ const messageType = this.extractMessageTypeFromTypeName(typeName);
237401
+ if (messageType) {
237402
+ return messageType;
237403
+ }
237366
237404
  }
237367
237405
  }
237368
237406
  return this.extractMessageTypeFromFunctionBodyText(node);
@@ -237701,7 +237739,10 @@ class IntegrationAnalyzer {
237701
237739
  if (args.length === 0) {
237702
237740
  return;
237703
237741
  }
237704
- const url = this.extractURLFromArg(args[0]);
237742
+ const firstArg = args[0];
237743
+ if (!firstArg)
237744
+ return;
237745
+ const url = this.extractURLFromArg(firstArg);
237705
237746
  if (!url) {
237706
237747
  return;
237707
237748
  }
@@ -237882,10 +237923,15 @@ class IntegrationAnalyzer {
237882
237923
  }
237883
237924
  }
237884
237925
  extractJSDocDescription(node) {
237885
- const jsDocs = node.getJsDocs?.() || [];
237926
+ if (!import_ts_morph5.Node.isJSDocable(node))
237927
+ return;
237928
+ const jsDocs = node.getJsDocs();
237886
237929
  if (jsDocs.length === 0)
237887
237930
  return;
237888
- const comment = jsDocs[0].getDescription().trim();
237931
+ const firstDoc = jsDocs[0];
237932
+ if (!firstDoc)
237933
+ return;
237934
+ const comment = firstDoc.getDescription().trim();
237889
237935
  return comment || undefined;
237890
237936
  }
237891
237937
  }
@@ -237927,17 +237973,17 @@ class ManifestParser {
237927
237973
  }
237928
237974
  const manifest = this.manifestData;
237929
237975
  return {
237930
- name: manifest.name || "Unknown Extension",
237931
- version: manifest.version || "0.0.0",
237932
- description: manifest.description,
237933
- manifestVersion: manifest.manifest_version || 2,
237976
+ name: manifest["name"] || "Unknown Extension",
237977
+ version: manifest["version"] || "0.0.0",
237978
+ description: manifest["description"],
237979
+ manifestVersion: manifest["manifest_version"] || 2,
237934
237980
  background: this.parseBackground(),
237935
237981
  contentScripts: this.parseContentScripts(),
237936
237982
  popup: this.parsePopup(),
237937
237983
  options: this.parseOptions(),
237938
237984
  devtools: this.parseDevtools(),
237939
- permissions: manifest.permissions || [],
237940
- hostPermissions: manifest.host_permissions || []
237985
+ permissions: manifest["permissions"] || [],
237986
+ hostPermissions: manifest["host_permissions"] || []
237941
237987
  };
237942
237988
  }
237943
237989
  getContextEntryPoints() {
@@ -238003,25 +238049,25 @@ class ManifestParser {
238003
238049
  parseBackground() {
238004
238050
  if (!this.manifestData)
238005
238051
  return;
238006
- const bg = this.manifestData.background;
238052
+ const bg = this.manifestData["background"];
238007
238053
  if (!bg)
238008
238054
  return;
238009
- if (bg.service_worker) {
238055
+ if (bg["service_worker"]) {
238010
238056
  return {
238011
238057
  type: "service_worker",
238012
- files: [bg.service_worker]
238058
+ files: [bg["service_worker"]]
238013
238059
  };
238014
238060
  }
238015
- if (bg.scripts) {
238061
+ if (bg["scripts"]) {
238016
238062
  return {
238017
238063
  type: "script",
238018
- files: bg.scripts
238064
+ files: bg["scripts"]
238019
238065
  };
238020
238066
  }
238021
- if (bg.page) {
238067
+ if (bg["page"]) {
238022
238068
  return {
238023
238069
  type: "script",
238024
- files: [bg.page]
238070
+ files: [bg["page"]]
238025
238071
  };
238026
238072
  }
238027
238073
  return;
@@ -238029,24 +238075,24 @@ class ManifestParser {
238029
238075
  parseContentScripts() {
238030
238076
  if (!this.manifestData)
238031
238077
  return;
238032
- const cs = this.manifestData.content_scripts;
238078
+ const cs = this.manifestData["content_scripts"];
238033
238079
  if (!cs || !Array.isArray(cs))
238034
238080
  return;
238035
238081
  return cs.map((script) => ({
238036
- matches: script.matches || [],
238037
- js: script.js || [],
238038
- css: script.css
238082
+ matches: script["matches"] || [],
238083
+ js: script["js"] || [],
238084
+ css: script["css"]
238039
238085
  }));
238040
238086
  }
238041
238087
  parsePopup() {
238042
238088
  if (!this.manifestData)
238043
238089
  return;
238044
- const action = this.manifestData.action || this.manifestData.browser_action;
238090
+ const action = this.manifestData["action"] || this.manifestData["browser_action"];
238045
238091
  if (!action)
238046
238092
  return;
238047
- if (action.default_popup) {
238093
+ if (action["default_popup"]) {
238048
238094
  return {
238049
- html: action.default_popup,
238095
+ html: action["default_popup"],
238050
238096
  default: true
238051
238097
  };
238052
238098
  }
@@ -238055,7 +238101,7 @@ class ManifestParser {
238055
238101
  parseOptions() {
238056
238102
  if (!this.manifestData)
238057
238103
  return;
238058
- const options = this.manifestData.options_ui || this.manifestData.options_page;
238104
+ const options = this.manifestData["options_ui"] || this.manifestData["options_page"];
238059
238105
  if (!options)
238060
238106
  return;
238061
238107
  if (typeof options === "string") {
@@ -238064,15 +238110,16 @@ class ManifestParser {
238064
238110
  openInTab: false
238065
238111
  };
238066
238112
  }
238113
+ const optionsObj = options;
238067
238114
  return {
238068
- page: options.page,
238069
- openInTab: options.open_in_tab
238115
+ page: optionsObj["page"],
238116
+ openInTab: optionsObj["open_in_tab"]
238070
238117
  };
238071
238118
  }
238072
238119
  parseDevtools() {
238073
238120
  if (!this.manifestData)
238074
238121
  return;
238075
- const devtools = this.manifestData.devtools_page;
238122
+ const devtools = this.manifestData["devtools_page"];
238076
238123
  if (!devtools)
238077
238124
  return;
238078
238125
  return {
@@ -238207,25 +238254,30 @@ class ProjectDetector {
238207
238254
  };
238208
238255
  }
238209
238256
  detectBackgroundEntry(manifest, entryPoints) {
238210
- const background = manifest.background;
238257
+ const background = manifest["background"];
238211
238258
  if (!background)
238212
238259
  return;
238213
- const file = background.service_worker || background.scripts?.[0] || background.page;
238260
+ const file = background["service_worker"] || background["scripts"]?.[0] || background["page"];
238214
238261
  if (file) {
238215
238262
  entryPoints["background"] = this.findSourceFile(file);
238216
238263
  }
238217
238264
  }
238218
238265
  detectContentScriptEntry(manifest, entryPoints) {
238219
- const contentScripts = manifest.content_scripts;
238266
+ const contentScripts = manifest["content_scripts"];
238220
238267
  if (!contentScripts || contentScripts.length === 0)
238221
238268
  return;
238222
- const firstScript = contentScripts[0].js?.[0];
238269
+ const firstScriptObj = contentScripts[0];
238270
+ if (!firstScriptObj)
238271
+ return;
238272
+ const firstScript = firstScriptObj["js"]?.[0];
238223
238273
  if (firstScript) {
238224
238274
  entryPoints["content"] = this.findSourceFile(firstScript);
238225
238275
  }
238226
238276
  }
238227
238277
  detectPopupEntry(manifest, entryPoints) {
238228
- const popup = manifest.action?.default_popup || manifest.browser_action?.default_popup;
238278
+ const action = manifest["action"];
238279
+ const browserAction = manifest["browser_action"];
238280
+ const popup = action?.["default_popup"] || browserAction?.["default_popup"];
238229
238281
  if (!popup)
238230
238282
  return;
238231
238283
  const jsFile = this.findAssociatedJS(join(this.projectRoot, popup));
@@ -238234,7 +238286,8 @@ class ProjectDetector {
238234
238286
  }
238235
238287
  }
238236
238288
  detectOptionsEntry(manifest, entryPoints) {
238237
- const options = manifest.options_ui?.page || manifest.options_page;
238289
+ const optionsUi = manifest["options_ui"];
238290
+ const options = optionsUi?.["page"] || manifest["options_page"];
238238
238291
  if (!options)
238239
238292
  return;
238240
238293
  const jsFile = this.findAssociatedJS(join(this.projectRoot, options));
@@ -238289,7 +238342,7 @@ class ProjectDetector {
238289
238342
  detectElectron(packageJson) {
238290
238343
  const entryPoints = {};
238291
238344
  const mainCandidates = [
238292
- packageJson.main,
238345
+ packageJson["main"],
238293
238346
  "src/main/index.ts",
238294
238347
  "src/electron/main.ts",
238295
238348
  "electron/main.ts",
@@ -238323,9 +238376,9 @@ class ProjectDetector {
238323
238376
  renderer: "Renderer Process"
238324
238377
  },
238325
238378
  metadata: {
238326
- name: packageJson.name,
238327
- version: packageJson.version,
238328
- description: packageJson.description
238379
+ name: packageJson["name"],
238380
+ version: packageJson["version"],
238381
+ description: packageJson["description"]
238329
238382
  }
238330
238383
  };
238331
238384
  }
@@ -238384,9 +238437,9 @@ class ProjectDetector {
238384
238437
  client: "Client"
238385
238438
  },
238386
238439
  metadata: {
238387
- name: packageJson.name,
238388
- version: packageJson.version,
238389
- description: packageJson.description
238440
+ name: packageJson["name"],
238441
+ version: packageJson["version"],
238442
+ description: packageJson["description"]
238390
238443
  }
238391
238444
  };
238392
238445
  }
@@ -238795,11 +238848,20 @@ class TypeExtractor {
238795
238848
  const handlerAnalysis = this.extractHandlerAnalysis();
238796
238849
  const validMessageTypes = this.filterAndLogMessageTypes(messageTypes, handlerAnalysis.messageTypes);
238797
238850
  const validHandlers = this.filterAndLogHandlers(handlerAnalysis.handlers);
238851
+ const completeHandlers = validHandlers.map((h) => ({
238852
+ messageType: h.messageType,
238853
+ node: h.node || "unknown",
238854
+ assignments: h.assignments || [],
238855
+ preconditions: h.preconditions || [],
238856
+ postconditions: h.postconditions || [],
238857
+ location: h.location,
238858
+ relationships: h.relationships
238859
+ }));
238798
238860
  return {
238799
238861
  stateType,
238800
238862
  messageTypes: validMessageTypes,
238801
238863
  fields,
238802
- handlers: validHandlers,
238864
+ handlers: completeHandlers,
238803
238865
  stateConstraints: handlerAnalysis.stateConstraints
238804
238866
  };
238805
238867
  }
@@ -238901,7 +238963,7 @@ class TypeExtractor {
238901
238963
  if (type2.getAliasSymbol()) {
238902
238964
  return this.extractFromTypeAlias(type2, typeName, sourceFile, warnings);
238903
238965
  }
238904
- if (type2.isConditionalType?.()) {
238966
+ if (typeof type2.isConditionalType === "function" && type2.isConditionalType()) {
238905
238967
  return this.extractFromConditionalType(type2, warnings);
238906
238968
  }
238907
238969
  if (type2.getText().includes("[K in ")) {
@@ -238966,7 +239028,10 @@ class TypeExtractor {
238966
239028
  if (parts.length < 2) {
238967
239029
  return messageTypes;
238968
239030
  }
238969
- const branches = parts[1].split(":");
239031
+ const secondPart = parts[1];
239032
+ if (!secondPart)
239033
+ return messageTypes;
239034
+ const branches = secondPart.split(":");
238970
239035
  for (const branch of branches) {
238971
239036
  const extracted = this.extractStringLiteralFromBranch(branch);
238972
239037
  if (extracted) {
@@ -239482,9 +239547,12 @@ class StructurizrDSLGenerator {
239482
239547
  }
239483
239548
  for (const [messageType, handlers2] of handlersByType) {
239484
239549
  const componentName = this.toComponentName(messageType);
239485
- const description = this.generateComponentDescription(messageType, handlers2[0]);
239486
- const tags = this.getComponentTags(messageType, handlers2[0]);
239487
- const properties = this.getComponentProperties(messageType, handlers2[0], contextType);
239550
+ const firstHandler = handlers2[0];
239551
+ if (!firstHandler)
239552
+ continue;
239553
+ const description = this.generateComponentDescription(messageType, firstHandler);
239554
+ const tags = this.getComponentTags(messageType, firstHandler);
239555
+ const properties = this.getComponentProperties(messageType, firstHandler, contextType);
239488
239556
  componentDefs.push({
239489
239557
  id: this.toId(componentName),
239490
239558
  name: componentName,
@@ -240015,7 +240083,8 @@ class StructurizrDSLGenerator {
240015
240083
  let stepCount = 0;
240016
240084
  for (const { handler, contextName: _contextName } of handlers2) {
240017
240085
  const handlerComponentId = this.toId(`${handler.messageType}_handler`);
240018
- for (const rel of handler.relationships) {
240086
+ const relationships = handler.relationships || [];
240087
+ for (const rel of relationships) {
240019
240088
  const toComponent = this.toId(rel.to);
240020
240089
  parts.push(` ${handlerComponentId} -> ${toComponent} "${rel.description}"`);
240021
240090
  stepCount++;
@@ -240096,7 +240165,7 @@ class StructurizrDSLGenerator {
240096
240165
  state: "Application state synchronization",
240097
240166
  general: "Message flow through the system"
240098
240167
  };
240099
- return descriptions[domain] || descriptions.general;
240168
+ return descriptions[domain] || descriptions["general"] || "Message flow through the system";
240100
240169
  }
240101
240170
  getUserAction(domain) {
240102
240171
  const actions = {
@@ -240105,7 +240174,7 @@ class StructurizrDSLGenerator {
240105
240174
  state: "Requests state",
240106
240175
  general: "Interacts"
240107
240176
  };
240108
- return actions[domain] || actions.general;
240177
+ return actions[domain] || actions["general"] || "Interacts";
240109
240178
  }
240110
240179
  getMessageDescription(messageType) {
240111
240180
  const type2 = messageType.toLowerCase();
@@ -240344,11 +240413,13 @@ class StructurizrDSLGenerator {
240344
240413
  }
240345
240414
  if (this.options.perspectives?.[comp.id]) {
240346
240415
  const perspectives = this.options.perspectives[comp.id];
240347
- parts.push(`${indent} perspectives {`);
240348
- for (const perspective of perspectives) {
240349
- parts.push(`${indent} "${this.escape(perspective.name)}" "${this.escape(perspective.description)}"`);
240416
+ if (perspectives) {
240417
+ parts.push(`${indent} perspectives {`);
240418
+ for (const perspective of perspectives) {
240419
+ parts.push(`${indent} "${this.escape(perspective.name)}" "${this.escape(perspective.description)}"`);
240420
+ }
240421
+ parts.push(`${indent} }`);
240350
240422
  }
240351
- parts.push(`${indent} }`);
240352
240423
  }
240353
240424
  parts.push(`${indent}}`);
240354
240425
  return parts.join(`
@@ -240545,11 +240616,12 @@ Your project contains ${contexts2.length} context(s) and ${allHandlers.length} m
240545
240616
  ### Contexts
240546
240617
 
240547
240618
  ${contexts2.map(([name, ctx]) => {
240619
+ const state = ctx.state;
240548
240620
  return `
240549
240621
  **${name}**
240550
240622
  Location: ${ctx.entryPoint}
240551
240623
  Handlers: ${ctx.handlers?.length || 0}
240552
- State variables: ${Object.keys(ctx.state?.variables || {}).length}`;
240624
+ State variables: ${Object.keys(state?.variables || {}).length}`;
240553
240625
  }).join(`
240554
240626
  `)}
240555
240627
 
@@ -240566,8 +240638,9 @@ ${allHandlers.length > 0 ? `
240566
240638
  Consider this handler from your codebase:
240567
240639
 
240568
240640
  \`\`\`typescript
240569
- // ${allHandlers[0].file}:${allHandlers[0].location?.line || "?"}
240570
- ${allHandlers[0].code || allHandlers[0].name || "Handler code not available"}
240641
+ // ${allHandlers[0]?.location?.file}:${allHandlers[0]?.location?.line || "?"}
240642
+ // Handler for message: ${allHandlers[0]?.messageType}
240643
+ // Node: ${allHandlers[0]?.node}
240571
240644
  \`\`\`
240572
240645
 
240573
240646
  Polly can translate this to TLA+ for formal verification.` : "No handlers detected in your project."}
@@ -240595,4 +240668,4 @@ export {
240595
240668
  generateTeachingMaterial
240596
240669
  };
240597
240670
 
240598
- //# debugId=F2EE93360E450F6364756E2164756E21
240671
+ //# debugId=792122C317EE04F564756E2164756E21