@fairfox/polly 0.72.0 → 0.73.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/dist/src/elysia/index.js +464 -4
- package/dist/src/elysia/index.js.map +6 -4
- package/dist/src/peer.d.ts +2 -0
- package/dist/src/peer.js +468 -4
- package/dist/src/peer.js.map +8 -5
- package/dist/src/polly-ui/ActionInput.d.ts +2 -1
- package/dist/src/polly-ui/ActionSelect.d.ts +2 -1
- package/dist/src/polly-ui/Button.d.ts +4 -0
- package/dist/src/polly-ui/Cluster.d.ts +2 -1
- package/dist/src/polly-ui/Code.d.ts +2 -1
- package/dist/src/polly-ui/Dropdown.d.ts +6 -0
- package/dist/src/polly-ui/Surface.d.ts +12 -1
- package/dist/src/polly-ui/Text.d.ts +23 -11
- package/dist/src/polly-ui/index.css +44 -18
- package/dist/src/polly-ui/index.js +118 -12
- package/dist/src/polly-ui/index.js.map +12 -11
- package/dist/src/polly-ui/internal/passthrough.d.ts +25 -0
- package/dist/src/polly-ui/styles.css +59 -18
- package/dist/src/polly-ui/theme.css +1 -0
- package/dist/src/shared/lib/peer-repo-server.d.ts +18 -0
- package/dist/src/shared/lib/sweep-sealed.d.ts +111 -0
- package/dist/tools/test/src/browser/run.js +42 -33
- package/dist/tools/test/src/browser/run.js.map +6 -5
- package/dist/tools/test/src/browser/runner-core.d.ts +32 -0
- package/dist/tools/test/src/e2e-mesh/index.js +193 -171
- package/dist/tools/test/src/e2e-mesh/index.js.map +4 -4
- package/dist/tools/test/src/visual/index.js +248 -229
- package/dist/tools/test/src/visual/index.js.map +5 -5
- package/dist/tools/verify/specs/tla/MeshSeed.cfg +27 -0
- package/dist/tools/verify/specs/tla/MeshSeed.tla +179 -0
- package/dist/tools/verify/specs/tla/README.md +11 -1
- package/dist/tools/verify/src/cli.js +79 -2
- package/dist/tools/verify/src/cli.js.map +7 -6
- package/dist/tools/visualize/src/cli.js +179 -3
- package/dist/tools/visualize/src/cli.js.map +6 -6
- package/package.json +3 -2
|
@@ -1864,14 +1864,37 @@ class HandlerExtractor {
|
|
|
1864
1864
|
return null;
|
|
1865
1865
|
const key = keyArg.getLiteralValue();
|
|
1866
1866
|
const variableName = this.getVariableNameFromParent(node) || key;
|
|
1867
|
+
const access = this.extractMeshAccess(args[2]);
|
|
1867
1868
|
return {
|
|
1868
1869
|
kind,
|
|
1869
1870
|
key,
|
|
1870
1871
|
variableName,
|
|
1871
1872
|
filePath,
|
|
1872
|
-
line: node.getStartLineNumber()
|
|
1873
|
+
line: node.getStartLineNumber(),
|
|
1874
|
+
...access ? { access } : {}
|
|
1873
1875
|
};
|
|
1874
1876
|
}
|
|
1877
|
+
extractMeshAccess(optionsArg) {
|
|
1878
|
+
if (!optionsArg || !Node4.isObjectLiteralExpression(optionsArg))
|
|
1879
|
+
return;
|
|
1880
|
+
const accessProp = optionsArg.getProperty("access");
|
|
1881
|
+
if (!accessProp || !Node4.isPropertyAssignment(accessProp))
|
|
1882
|
+
return;
|
|
1883
|
+
const accessObj = accessProp.getInitializer();
|
|
1884
|
+
if (!accessObj || !Node4.isObjectLiteralExpression(accessObj))
|
|
1885
|
+
return;
|
|
1886
|
+
const predicateText = (name) => {
|
|
1887
|
+
const prop = accessObj.getProperty(name);
|
|
1888
|
+
if (!prop || !Node4.isPropertyAssignment(prop))
|
|
1889
|
+
return;
|
|
1890
|
+
return prop.getInitializer()?.getText().replace(/\s+/g, " ").trim();
|
|
1891
|
+
};
|
|
1892
|
+
const read = predicateText("read");
|
|
1893
|
+
const write = predicateText("write");
|
|
1894
|
+
if (read === undefined && write === undefined)
|
|
1895
|
+
return;
|
|
1896
|
+
return { read: read ?? "unset", write: write ?? "unset" };
|
|
1897
|
+
}
|
|
1875
1898
|
analyzeFileAndImports(sourceFile, handlers, messageTypes, invalidMessageTypes, stateConstraints, globalStateConstraints, verifiedStates, resources) {
|
|
1876
1899
|
const filePath = sourceFile.getFilePath();
|
|
1877
1900
|
if (this.analyzedFiles.has(filePath)) {
|
|
@@ -4456,7 +4479,7 @@ class ArchitectureAnalyzer {
|
|
|
4456
4479
|
}
|
|
4457
4480
|
}
|
|
4458
4481
|
const handlerExtractor = new HandlerExtractor(this.options.tsConfigPath, contextOverrides.size > 0 ? contextOverrides : undefined);
|
|
4459
|
-
const { handlers } = handlerExtractor.extractHandlers();
|
|
4482
|
+
const { handlers, meshOrPeerSignals } = handlerExtractor.extractHandlers();
|
|
4460
4483
|
const contexts = this.analyzeContexts(entryPoints, handlers);
|
|
4461
4484
|
const flowAnalyzer = new FlowAnalyzer(this.options.tsConfigPath, handlers, contextOverrides.size > 0 ? contextOverrides : undefined);
|
|
4462
4485
|
const messageFlows = flowAnalyzer.analyzeFlows();
|
|
@@ -4473,6 +4496,7 @@ class ArchitectureAnalyzer {
|
|
|
4473
4496
|
contexts,
|
|
4474
4497
|
messageFlows,
|
|
4475
4498
|
integrations,
|
|
4499
|
+
...meshOrPeerSignals.length > 0 ? { meshOrPeerSignals } : {},
|
|
4476
4500
|
...adrs.adrs.length > 0 ? { adrs } : {},
|
|
4477
4501
|
...repository ? { repository } : {}
|
|
4478
4502
|
};
|
|
@@ -4628,6 +4652,21 @@ var DEFAULT_ELEMENT_STYLES = {
|
|
|
4628
4652
|
Container: {
|
|
4629
4653
|
background: DEFAULT_COLORS.container,
|
|
4630
4654
|
color: DEFAULT_COLORS.textLight
|
|
4655
|
+
},
|
|
4656
|
+
"Mesh Document": {
|
|
4657
|
+
shape: "Cylinder",
|
|
4658
|
+
background: DEFAULT_COLORS.subscribeHandler,
|
|
4659
|
+
color: DEFAULT_COLORS.textLight
|
|
4660
|
+
},
|
|
4661
|
+
"Peer Document": {
|
|
4662
|
+
shape: "Cylinder",
|
|
4663
|
+
background: DEFAULT_COLORS.queryHandler,
|
|
4664
|
+
color: DEFAULT_COLORS.textDark
|
|
4665
|
+
},
|
|
4666
|
+
"Mesh Transport": {
|
|
4667
|
+
shape: "Pipe",
|
|
4668
|
+
background: DEFAULT_COLORS.service,
|
|
4669
|
+
color: DEFAULT_COLORS.textLight
|
|
4631
4670
|
}
|
|
4632
4671
|
};
|
|
4633
4672
|
var DEFAULT_RELATIONSHIP_STYLES = {
|
|
@@ -4654,6 +4693,29 @@ var DEFAULT_RELATIONSHIP_STYLES = {
|
|
|
4654
4693
|
var DEFAULT_THEME = "https://static.structurizr.com/themes/default/theme.json";
|
|
4655
4694
|
|
|
4656
4695
|
// tools/visualize/src/codegen/structurizr.ts
|
|
4696
|
+
var MESH_TRANSPORT_NODES = [
|
|
4697
|
+
{
|
|
4698
|
+
id: "mesh_net_adapter",
|
|
4699
|
+
name: "MeshNetworkAdapter",
|
|
4700
|
+
description: "Signs and encrypts every mesh operation"
|
|
4701
|
+
},
|
|
4702
|
+
{
|
|
4703
|
+
id: "mesh_webrtc_adapter",
|
|
4704
|
+
name: "MeshWebRTCAdapter",
|
|
4705
|
+
description: "Peer-to-peer WebRTC data channels"
|
|
4706
|
+
},
|
|
4707
|
+
{
|
|
4708
|
+
id: "mesh_signaling_client",
|
|
4709
|
+
name: "MeshSignalingClient",
|
|
4710
|
+
description: "WebRTC offer/answer signalling"
|
|
4711
|
+
},
|
|
4712
|
+
{
|
|
4713
|
+
id: "mesh_signaling_endpoint",
|
|
4714
|
+
name: "Signalling endpoint",
|
|
4715
|
+
description: "The rendezvous server peers exchange WebRTC offers through"
|
|
4716
|
+
}
|
|
4717
|
+
];
|
|
4718
|
+
|
|
4657
4719
|
class StructurizrDSLGenerator {
|
|
4658
4720
|
analysis;
|
|
4659
4721
|
options;
|
|
@@ -4749,6 +4811,12 @@ class StructurizrDSLGenerator {
|
|
|
4749
4811
|
for (const [contextType, contextInfo] of Object.entries(this.analysis.contexts)) {
|
|
4750
4812
|
parts.push(this.generateContainer(contextType, contextInfo));
|
|
4751
4813
|
}
|
|
4814
|
+
const meshDocs = this.generateMeshDocuments();
|
|
4815
|
+
if (meshDocs)
|
|
4816
|
+
parts.push(meshDocs);
|
|
4817
|
+
const meshTransport = this.generateMeshTransport();
|
|
4818
|
+
if (meshTransport)
|
|
4819
|
+
parts.push(meshTransport);
|
|
4752
4820
|
parts.push(this.generateContainerRelationships());
|
|
4753
4821
|
parts.push(" }");
|
|
4754
4822
|
return parts.join(`
|
|
@@ -4769,6 +4837,49 @@ class StructurizrDSLGenerator {
|
|
|
4769
4837
|
return parts.join(`
|
|
4770
4838
|
`);
|
|
4771
4839
|
}
|
|
4840
|
+
generateMeshDocuments() {
|
|
4841
|
+
const signals = this.analysis.meshOrPeerSignals ?? [];
|
|
4842
|
+
if (signals.length === 0)
|
|
4843
|
+
return "";
|
|
4844
|
+
const parts = [];
|
|
4845
|
+
const seen = new Set;
|
|
4846
|
+
for (const sig of signals) {
|
|
4847
|
+
if (seen.has(sig.key))
|
|
4848
|
+
continue;
|
|
4849
|
+
seen.add(sig.key);
|
|
4850
|
+
const kindLabel = sig.kind === "mesh" ? "Mesh Document" : "Peer Document";
|
|
4851
|
+
const access = sig.access ? ` · access read=${this.clip(sig.access.read)} write=${this.clip(sig.access.write)}` : "";
|
|
4852
|
+
const description = `${kindLabel} — deriveDocumentId('${sig.key}')${access}`;
|
|
4853
|
+
parts.push(` ${this.meshDocId(sig.key)} = container "${this.escape(sig.key)}" "${this.escape(description)}" "$${sig.kind}State" {`);
|
|
4854
|
+
parts.push(` tags "${kindLabel}"`);
|
|
4855
|
+
parts.push(" }");
|
|
4856
|
+
}
|
|
4857
|
+
return parts.join(`
|
|
4858
|
+
`);
|
|
4859
|
+
}
|
|
4860
|
+
meshDocId(key) {
|
|
4861
|
+
return `mesh_doc_${this.toId(key)}`;
|
|
4862
|
+
}
|
|
4863
|
+
clip(text, max = 32) {
|
|
4864
|
+
return text.length > max ? `${text.slice(0, max - 1)}…` : text;
|
|
4865
|
+
}
|
|
4866
|
+
contextForFilePath(filePath) {
|
|
4867
|
+
const contextKeys = Object.keys(this.analysis.contexts);
|
|
4868
|
+
if (contextKeys.length === 1)
|
|
4869
|
+
return contextKeys[0];
|
|
4870
|
+
let best;
|
|
4871
|
+
for (const [context, info] of Object.entries(this.analysis.contexts)) {
|
|
4872
|
+
const entry = info.entryPoint;
|
|
4873
|
+
if (!entry)
|
|
4874
|
+
continue;
|
|
4875
|
+
const dir = entry.slice(0, entry.lastIndexOf("/") + 1);
|
|
4876
|
+
if (dir.length > 0 && filePath.includes(dir)) {
|
|
4877
|
+
if (!best || dir.length > best.length)
|
|
4878
|
+
best = { context, length: dir.length };
|
|
4879
|
+
}
|
|
4880
|
+
}
|
|
4881
|
+
return best?.context;
|
|
4882
|
+
}
|
|
4772
4883
|
generateComponents(contextType, contextInfo) {
|
|
4773
4884
|
const parts = [];
|
|
4774
4885
|
const componentDefs = this.buildComponentDefinitionsFromHandlers(contextInfo, contextType);
|
|
@@ -5089,9 +5200,74 @@ class StructurizrDSLGenerator {
|
|
|
5089
5200
|
parts.push(...this.generateUserRelationships());
|
|
5090
5201
|
parts.push(...this.generateMessageFlowRelationships());
|
|
5091
5202
|
parts.push(...this.generateExternalAPIRelationships());
|
|
5203
|
+
parts.push(...this.generateMeshRelationships());
|
|
5204
|
+
parts.push(...this.generateMeshTransportRelationships());
|
|
5205
|
+
return parts.join(`
|
|
5206
|
+
`);
|
|
5207
|
+
}
|
|
5208
|
+
generateMeshRelationships() {
|
|
5209
|
+
const signals = this.analysis.meshOrPeerSignals ?? [];
|
|
5210
|
+
const parts = [];
|
|
5211
|
+
const seen = new Set;
|
|
5212
|
+
for (const sig of signals) {
|
|
5213
|
+
const context = this.contextForFilePath(sig.filePath);
|
|
5214
|
+
if (!context)
|
|
5215
|
+
continue;
|
|
5216
|
+
const edgeKey = `${context}->${sig.key}`;
|
|
5217
|
+
if (seen.has(edgeKey))
|
|
5218
|
+
continue;
|
|
5219
|
+
seen.add(edgeKey);
|
|
5220
|
+
parts.push(` extension.${context} -> extension.${this.meshDocId(sig.key)} "syncs ${this.escape(sig.key)}"`);
|
|
5221
|
+
}
|
|
5222
|
+
return parts;
|
|
5223
|
+
}
|
|
5224
|
+
meshSignalKinds() {
|
|
5225
|
+
const signals = this.analysis.meshOrPeerSignals ?? [];
|
|
5226
|
+
return {
|
|
5227
|
+
mesh: signals.some((s) => s.kind === "mesh"),
|
|
5228
|
+
peer: signals.some((s) => s.kind === "peer")
|
|
5229
|
+
};
|
|
5230
|
+
}
|
|
5231
|
+
generateMeshTransport() {
|
|
5232
|
+
const { mesh, peer } = this.meshSignalKinds();
|
|
5233
|
+
if (!mesh && !peer)
|
|
5234
|
+
return "";
|
|
5235
|
+
const parts = [];
|
|
5236
|
+
if (mesh) {
|
|
5237
|
+
for (const node of MESH_TRANSPORT_NODES) {
|
|
5238
|
+
parts.push(` ${node.id} = container "${node.name}" "${this.escape(node.description)}" "Mesh Transport" {`);
|
|
5239
|
+
parts.push(' tags "Mesh Transport"');
|
|
5240
|
+
parts.push(" }");
|
|
5241
|
+
}
|
|
5242
|
+
}
|
|
5243
|
+
if (peer) {
|
|
5244
|
+
parts.push(` peer_relay = container "Peer relay" "${this.escape("The always-on relay $peerState syncs through")}" "Peer Transport" {`);
|
|
5245
|
+
parts.push(' tags "Mesh Transport"');
|
|
5246
|
+
parts.push(" }");
|
|
5247
|
+
}
|
|
5092
5248
|
return parts.join(`
|
|
5093
5249
|
`);
|
|
5094
5250
|
}
|
|
5251
|
+
generateMeshTransportRelationships() {
|
|
5252
|
+
const { mesh, peer } = this.meshSignalKinds();
|
|
5253
|
+
const parts = [];
|
|
5254
|
+
if (mesh) {
|
|
5255
|
+
parts.push(' extension.mesh_net_adapter -> extension.mesh_webrtc_adapter "wraps"');
|
|
5256
|
+
parts.push(' extension.mesh_webrtc_adapter -> extension.mesh_signaling_client "negotiates via"');
|
|
5257
|
+
parts.push(' extension.mesh_signaling_client -> extension.mesh_signaling_endpoint "connects to"');
|
|
5258
|
+
}
|
|
5259
|
+
if (!mesh && !peer)
|
|
5260
|
+
return parts;
|
|
5261
|
+
const seen = new Set;
|
|
5262
|
+
for (const sig of this.analysis.meshOrPeerSignals ?? []) {
|
|
5263
|
+
if (seen.has(sig.key))
|
|
5264
|
+
continue;
|
|
5265
|
+
seen.add(sig.key);
|
|
5266
|
+
const target = sig.kind === "mesh" ? "mesh_net_adapter" : "peer_relay";
|
|
5267
|
+
parts.push(` extension.${this.meshDocId(sig.key)} -> extension.${target} "syncs through"`);
|
|
5268
|
+
}
|
|
5269
|
+
return parts;
|
|
5270
|
+
}
|
|
5095
5271
|
generateUserRelationships() {
|
|
5096
5272
|
const parts = [];
|
|
5097
5273
|
const uiContexts = ["popup", "options", "devtools"];
|
|
@@ -6290,4 +6466,4 @@ main().catch((_error) => {
|
|
|
6290
6466
|
process.exit(1);
|
|
6291
6467
|
});
|
|
6292
6468
|
|
|
6293
|
-
//# debugId=
|
|
6469
|
+
//# debugId=2FC255DE0B3BC47C64756E2164756E21
|