xcode-graph 0.1.1 → 0.2.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/README.md CHANGED
@@ -1,5 +1,5 @@
1
1
  <p align="center">
2
- <img src="docs/public/xcode-graph-icon-readme.png" alt="XcodeGraph" width="180" />
2
+ <img src="https://ajkolean.github.io/xcode-graph/xcode-graph-icon-readme.png" alt="XcodeGraph" width="180" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">xcode-graph</h1>
@@ -17,6 +17,8 @@
17
17
  <a href="https://github.com/ajkolean/xcode-graph/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="MIT License" /></a>
18
18
  <a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/types-TypeScript-3178C6" alt="TypeScript" /></a>
19
19
  <a href="https://lit.dev"><img src="https://img.shields.io/badge/built%20with-Lit-324FFF" alt="Built with Lit" /></a>
20
+ <a href="https://app.deepsource.com/gh/ajkolean/xcode-graph/"><img src="https://app.deepsource.com/gh/ajkolean/xcode-graph.svg/?label=code+coverage&show_trend=true&token=bpb3vqsaKxh829cTU452ydmW" alt="DeepSource Code Coverage" /></a>
21
+ <a href="https://app.deepsource.com/gh/ajkolean/xcode-graph/"><img src="https://app.deepsource.com/gh/ajkolean/xcode-graph.svg/?label=active+issues&show_trend=true&token=bpb3vqsaKxh829cTU452ydmW" alt="DeepSource Active Issues" /></a>
20
22
  </p>
21
23
 
22
24
  <p align="center">
@@ -29,16 +31,18 @@
29
31
 
30
32
  ## Features
31
33
 
32
- - **Interactive Canvas** — Zoom, pan, and click through dependency graphs with hardware-accelerated rendering
34
+ - **Interactive Canvas** — Zoom, pan, and click through dependency graphs with hardware-accelerated SVG rendering
33
35
  - **Cluster Layouts** — Nodes grouped by project into visual clusters using a two-phase hierarchical layout (ELK + D3-force)
34
- - **Search & Filter** — Filter by type, origin, platform, or project; instant search with highlighting
35
- - **Transitive Dependencies** — Highlight the full dependency chain for any node
36
- - **Circular Dependency Detection** — Identifies and warns about cycles in the graph
36
+ - **Search & Filter** — Filter by node type, origin, platform, or project; instant search with highlighting
37
+ - **Transitive Dependencies** — Highlight the full dependency chain (direct, transitive, dependents, or both) for any node
38
+ - **Circular Dependency Detection** — Automatically identifies and warns about cycles in the graph
37
39
  - **File Upload** — Drag-and-drop or file picker for loading XcodeGraph JSON
38
- - **Theming** — 20+ CSS custom properties for complete visual customization
39
- - **Dark & Light Mode** — Automatic adaptation to system preference
40
- - **TypeScript** — Full type definitions included
40
+ - **Theming** — 30+ CSS custom properties for complete visual customization
41
+ - **Dark & Light Mode** — Automatic adaptation to `prefers-color-scheme`, or force a specific mode
42
+ - **Accessible** — ARIA labels, keyboard navigation, focus traps, and `prefers-reduced-motion` support
43
+ - **TypeScript** — Full type definitions with strict mode
41
44
  - **Zero Config** — Single `<xcode-graph>` element, works in any framework or vanilla HTML
45
+ - **CDN Ready** — Self-contained ES module bundle with code-split Zod validation
42
46
 
43
47
  ## Installation
44
48
 
@@ -81,7 +85,7 @@ const app = document.querySelector('xcode-graph');
81
85
  app.loadRawGraph(xcodeGraphJson);
82
86
  ```
83
87
 
84
- `loadRawGraph` validates and transforms the raw JSON into the internal `GraphNode` / `GraphEdge` format automatically.
88
+ `loadRawGraph` validates and transforms the raw JSON into the internal `GraphNode` / `GraphEdge` format automatically. The Zod validation layer is lazy-loaded on first call to keep the main bundle small. Unknown enum values produce warnings rather than errors, so the component is forward-compatible with newer Xcode project types.
85
89
 
86
90
  ### From a CDN (no bundler)
87
91
 
@@ -101,54 +105,218 @@ app.loadRawGraph(xcodeGraphJson);
101
105
  </html>
102
106
  ```
103
107
 
108
+ ### With file upload
109
+
110
+ ```html
111
+ <xcode-graph show-upload></xcode-graph>
112
+ ```
113
+
114
+ Users can drag-and-drop or use the file picker to load their own XcodeGraph JSON files.
115
+
116
+ ## Component API
117
+
118
+ ### Properties
119
+
120
+ | Property | Attribute | Type | Default | Description |
121
+ |---|---|---|---|---|
122
+ | `nodes` | — | `GraphNode[]` | `undefined` | Graph nodes to visualize |
123
+ | `edges` | — | `GraphEdge[]` | `undefined` | Graph edges connecting nodes |
124
+ | `layoutOptions` | — | `LayoutOptions` | `undefined` | ELK + D3-force layout configuration overrides |
125
+ | `showUpload` | `show-upload` | `boolean` | `false` | Show the file upload overlay |
126
+ | `colorScheme` | `color-scheme` | `'light' \| 'dark' \| 'auto'` | `'auto'` | Color scheme preference |
127
+
128
+ ### Methods
129
+
130
+ | Method | Parameters | Description |
131
+ |---|---|---|
132
+ | `loadRawGraph()` | `raw: unknown` | Load and transform raw XcodeGraph JSON (`tuist graph --format json` output) |
133
+
134
+ See the [Component API reference](https://ajkolean.github.io/xcode-graph/reference/component-api) for events, CSS custom properties, and sizing details.
135
+
104
136
  ## Data Shape
105
137
 
106
138
  <details>
107
139
  <summary><strong>GraphNode</strong></summary>
108
140
 
109
- | Field | Type | Description |
110
- |---------------------|-----------------------------|----------------------------------------------------------|
111
- | `id` | `string` | Unique identifier |
112
- | `name` | `string` | Display name |
113
- | `type` | `NodeType` | `app`, `framework`, `library`, `package`, `test-unit`, `test-ui`, `cli` |
114
- | `platform` | `Platform` | `iOS`, `macOS`, `visionOS`, `tvOS`, `watchOS` |
115
- | `origin` | `Origin` | `local` or `external` |
116
- | `project` | `string?` | Owning project name |
117
- | `deploymentTargets` | `Record<Platform, string>?` | Multi-platform deployment targets |
141
+ | Field | Type | Required | Description |
142
+ |---|---|---|---|
143
+ | `id` | `string` | Yes | Unique identifier |
144
+ | `name` | `string` | Yes | Display name |
145
+ | `type` | `NodeType` | Yes | `app`, `framework`, `library`, `package`, `test-unit`, `test-ui`, `cli` |
146
+ | `platform` | `Platform` | Yes | `iOS`, `macOS`, `visionOS`, `tvOS`, `watchOS` |
147
+ | `origin` | `Origin` | Yes | `local` or `external` |
148
+ | `project` | `string?` | No | Parent project or package name |
149
+ | `deploymentTargets` | `DeploymentTargets?` | No | Min version per platform |
150
+ | `buildSettings` | `BuildSettings?` | No | Swift version, compilation conditions, code signing |
151
+ | `bundleId` | `string?` | No | Bundle identifier |
152
+ | `sourceCount` | `number?` | No | Total source file count |
153
+ | `resourceCount` | `number?` | No | Total resource file count |
154
+ | `destinations` | `Destination[]?` | No | Supported device destinations |
155
+ | `tags` | `string[]?` | No | Metadata tags |
156
+ | `foreignBuild` | `ForeignBuildInfo?` | No | External build system info (Bazel, CMake, KMP/Gradle) |
118
157
 
119
158
  </details>
120
159
 
121
160
  <details>
122
161
  <summary><strong>GraphEdge</strong></summary>
123
162
 
124
- | Field | Type | Description |
125
- |----------------------|-------------------|--------------------------------------------|
126
- | `source` | `string` | ID of the source node (depends on target) |
127
- | `target` | `string` | ID of the target node (dependency) |
128
- | `kind` | `DependencyKind?` | `target`, `project`, `sdk`, `xcframework` |
129
- | `platformConditions` | `Platform[]?` | Platform conditions for this edge |
163
+ | Field | Type | Required | Description |
164
+ |---|---|---|---|
165
+ | `source` | `string` | Yes | ID of the source node (depends on target) |
166
+ | `target` | `string` | Yes | ID of the target node (dependency) |
167
+ | `kind` | `DependencyKind?` | No | `target`, `project`, `sdk`, `xcframework` |
168
+ | `platformConditions` | `Platform[]?` | No | Platform conditions for this edge |
130
169
 
131
170
  </details>
132
171
 
133
- These are the core fields. See the full type definitions in the [API Reference](https://ajkolean.github.io/xcode-graph/api/).
172
+ See the full type definitions in the [Data Types reference](https://ajkolean.github.io/xcode-graph/reference/data-types).
134
173
 
135
174
  ## Theming
136
175
 
137
- Customize the look with CSS custom properties:
176
+ The component is fully themeable via CSS custom properties. Set `--graph-*` properties on the `<xcode-graph>` element or any ancestor:
138
177
 
139
178
  ```css
140
179
  xcode-graph {
180
+ /* Core */
141
181
  --graph-bg: #1a1a2e;
142
- --graph-accent: #7c3aed;
182
+ --graph-bg-secondary: #16213e;
143
183
  --graph-text: #e2e8f0;
184
+ --graph-text-muted: rgba(226, 232, 240, 0.5);
185
+ --graph-accent: #7c3aed;
186
+ --graph-accent-dim: rgba(124, 58, 237, 0.15);
187
+ --graph-border: rgba(255, 255, 255, 0.08);
188
+ --graph-canvas-bg: #1a1a2e;
189
+ --graph-radius: 8px;
190
+
191
+ /* Node type colors */
144
192
  --graph-node-app: #f59e0b;
145
193
  --graph-node-framework: #0ea5e9;
146
- --graph-node-package: #10b981;
147
- --graph-radius: 8px;
194
+ --graph-node-library: #22c55e;
195
+ --graph-node-test: #ec4899;
196
+ --graph-node-cli: #3b82f6;
197
+ --graph-node-package: #eab308;
198
+
199
+ /* Platform colors */
200
+ --graph-platform-ios: #007AFF;
201
+ --graph-platform-macos: #64D2FF;
202
+ --graph-platform-tvos: #B87BFF;
203
+ --graph-platform-watchos: #5AC8FA;
204
+ --graph-platform-visionos: #7D7AFF;
205
+
206
+ /* Typography */
207
+ --graph-font: 'Inter', system-ui, sans-serif;
208
+ --graph-font-mono: 'JetBrains Mono', ui-monospace, monospace;
148
209
  }
149
210
  ```
150
211
 
151
- See the [Component API reference](https://ajkolean.github.io/xcode-graph/reference/component-api) for all available properties.
212
+ ### Color scheme
213
+
214
+ The component adapts to `prefers-color-scheme` automatically. Both dark and light token sets are built in. To force a specific mode:
215
+
216
+ ```html
217
+ <xcode-graph color-scheme="light"></xcode-graph>
218
+ <xcode-graph color-scheme="dark"></xcode-graph>
219
+ <xcode-graph color-scheme="auto"></xcode-graph> <!-- default -->
220
+ ```
221
+
222
+ See the [Component API reference](https://ajkolean.github.io/xcode-graph/reference/component-api) for all available properties with dark and light mode defaults.
223
+
224
+ ## Layout Engine
225
+
226
+ The graph uses a two-phase layout pipeline:
227
+
228
+ 1. **Macro layout (ELK)** — Positions clusters (groups of related nodes) using the ELK layered algorithm for hierarchical structure
229
+ 2. **Micro layout (D3-force)** — Positions nodes within each cluster using physics-based force simulation with boundary constraints, radial orbits, and collision avoidance
230
+
231
+ Override layout parameters via the `layoutOptions` property:
232
+
233
+ ```js
234
+ const app = document.querySelector('xcode-graph');
235
+ app.layoutOptions = {
236
+ configOverrides: {
237
+ elkDirection: 'RIGHT', // LEFT | RIGHT | UP | DOWN
238
+ elkNodeSpacing: 300,
239
+ elkLayerSpacing: 400,
240
+ iterations: 500,
241
+ },
242
+ hooks: {
243
+ onLayoutComplete: (result) => {
244
+ console.log('Layout done:', result.clusters.length, 'clusters');
245
+ },
246
+ },
247
+ };
248
+ ```
249
+
250
+ See the [Layout Configuration reference](https://ajkolean.github.io/xcode-graph/reference/layout-configuration) for all available parameters.
251
+
252
+ ## Architecture
253
+
254
+ ```
255
+ src/
256
+ ├── components/ Root <xcode-graph> web component
257
+ ├── graph/
258
+ │ ├── components/ Canvas rendering (SVG, nodes, edges, tooltips)
259
+ │ ├── controllers/ Layout orchestration, interaction handling, animation loop
260
+ │ ├── layout/ ELK hierarchical + D3-force physics pipeline
261
+ │ ├── signals/ Graph state (selection, highlights, view mode)
262
+ │ └── utils/ Traversal, filtering, canvas theming
263
+ ├── services/
264
+ │ ├── graph-data-service.ts O(1) indexed data layer
265
+ │ ├── graph-analysis-service.ts Circular dependency & path detection
266
+ │ ├── xcode-graph.service.ts Raw Tuist JSON → internal format
267
+ │ ├── xcode-graph.validation.ts Zod schema validation
268
+ │ ├── graph-loader.ts Progressive loading
269
+ │ ├── graph-stats-service.ts Graph statistics
270
+ │ └── error-service.ts User-facing error handling
271
+ ├── shared/
272
+ │ ├── schemas/ Type definitions (GraphNode, GraphEdge, enums)
273
+ │ ├── signals/ Global state (filters, UI, errors)
274
+ │ ├── controllers/ Zag-js, keyboard shortcuts, focus traps, resize
275
+ │ └── machines/ Zag-js state machines
276
+ ├── ui/
277
+ │ ├── layout/ Tab orchestrator, header, sidebar
278
+ │ ├── components/ 80+ UI components (filters, panels, search, badges)
279
+ │ └── utils/ Colors, icons, sizing, viewport
280
+ ├── styles/
281
+ │ ├── tokens.css Design tokens (dark + light mode)
282
+ │ └── theme-utils.ts Color manipulation, contrast checking
283
+ └── index.ts Library entry point (re-exports public API)
284
+ ```
285
+
286
+ ### Key Technologies
287
+
288
+ | Concern | Technology |
289
+ |---|---|
290
+ | Web components | [Lit](https://lit.dev) 3.x |
291
+ | State management | [Lit Signals](https://github.com/nicklama/xcode-graph) (`@lit-labs/signals`) |
292
+ | UI state machines | [Zag-js](https://zagjs.com) |
293
+ | Hierarchical layout | [ELK.js](https://github.com/kieler/elkjs) |
294
+ | Physics simulation | [D3-force](https://d3js.org/d3-force) |
295
+ | Schema validation | [Zod](https://zod.dev) 4.x |
296
+ | Color utilities | [colord](https://colord.omgovich.dev/) |
297
+ | Web workers | [Comlink](https://github.com/nicklama/xcode-graph) |
298
+ | Focus management | [focus-trap](https://github.com/focus-trap/focus-trap) |
299
+
300
+ ### Services
301
+
302
+ | Service | Purpose |
303
+ |---|---|
304
+ | `GraphDataService` | Centralized O(1) data layer with indexed lookups by type, project, platform, and origin. Provides dependency queries (direct, transitive, BFS traversal) and cluster support. |
305
+ | `GraphAnalysisService` | Stateless algorithms for graph analysis: BFS path detection and DFS cycle finding. |
306
+ | `XcodeGraphService` | Transforms raw Tuist/XcodeGraph JSON into the internal `GraphData` format. Forward-compatible — unknown enum values produce warnings, not crashes. |
307
+ | `ErrorService` | Singleton error handling with toast notifications. Auto-dismiss timers, severity levels, and user-facing messages. |
308
+ | `GraphStatsService` | Computes graph statistics (node counts, edge counts, connectivity metrics). |
309
+ | `GraphLoaderService` | Progressive/lazy loading with progress tracking. |
310
+
311
+ ### State Management
312
+
313
+ The component uses [Lit Signals](https://lit.dev/docs/data/signals/) for reactive state:
314
+
315
+ - **Graph signals** — `selectedNode`, `selectedCluster`, `hoveredNode`, `circularDependencies`, highlight toggles
316
+ - **Filter signals** — Active filters for node types, platforms, origins, projects, packages
317
+ - **UI signals** — Zoom level, search query, animation toggle, active tab
318
+ - **Display computed** — Derived filtered/highlighted data based on all active filters and selections
319
+ - **Error signals** — Active error/warning state
152
320
 
153
321
  ## Swift Integration
154
322
 
@@ -159,30 +327,84 @@ GET / → HTML page loading <xcode-graph> from jsdelivr
159
327
  GET /graph.json → Raw XcodeGraph JSON data
160
328
  ```
161
329
 
330
+ ```swift
331
+ import XcodeGraphServer
332
+
333
+ let server = try GraphServer(graph: graph)
334
+ try server.start() // opens browser, blocks until ctrl-c
335
+ ```
336
+
337
+ The Swift package includes:
338
+ - **XcodeGraphServer** — SwiftNIO HTTP server (binds to `localhost:8081`)
339
+ - **XcodeGraphCLI** — Command-line interface
340
+ - **TransformGraph** — Swift code analyzer for type extraction
341
+
162
342
  See the [Swift Integration guide](https://ajkolean.github.io/xcode-graph/guide/swift-integration) for details.
163
343
 
164
- ## Documentation
344
+ ## IDE Support
165
345
 
166
- Full docs at **[ajkolean.github.io/xcode-graph](https://ajkolean.github.io/xcode-graph/)**
346
+ The package ships metadata files for editor integration:
167
347
 
168
- - [Getting Started](https://ajkolean.github.io/xcode-graph/guide/) Installation, usage, and data shape
169
- - [Swift Integration](https://ajkolean.github.io/xcode-graph/guide/swift-integration) — Embedding in a Swift server
170
- - [Component API](https://ajkolean.github.io/xcode-graph/reference/component-api) Properties, methods, events, CSS custom properties
171
- - [Layout Configuration](https://ajkolean.github.io/xcode-graph/reference/layout-configuration) ELK & D3-force parameters
172
- - [API Reference](https://ajkolean.github.io/xcode-graph/api/) Full TypeDoc reference
348
+ | File | Editor | Purpose |
349
+ |---|---|---|
350
+ | `custom-elements.json` | All | Custom Elements Manifest (CEM) |
351
+ | `web-types.json` | WebStorm/JetBrains | Component and property completions |
352
+ | `vscode.html-custom-data.json` | VS Code | HTML tag and attribute IntelliSense |
353
+ | `vscode.css-custom-data.json` | VS Code | CSS custom property completions |
173
354
 
174
355
  ## Development
175
356
 
176
357
  ```bash
177
- pnpm install # Install dependencies
178
- pnpm dev # Start dev server
179
- pnpm test:run # Run tests
180
- pnpm check # Lint + format (Biome)
181
- pnpm docs:dev # Start docs dev server
182
- pnpm docs:api # Generate TypeDoc API reference
183
- pnpm analyze # Regenerate Custom Elements Manifest
358
+ pnpm install # Install dependencies
359
+ pnpm dev # Start dev server (port 3000)
360
+ pnpm test:run # Run unit tests
361
+ pnpm test:coverage # Run tests with coverage
362
+ pnpm check # Lint + format (Biome) + token validation
363
+ pnpm build:lib # Build production library bundle
364
+ pnpm docs:dev # Start docs dev server (port 5174)
365
+ pnpm docs:api # Generate TypeDoc API reference
366
+ pnpm analyze # Regenerate Custom Elements Manifest
367
+ pnpm size # Check bundle size limits
368
+ pnpm size:why # Analyze bundle composition
369
+ pnpm depcheck # Check for unused dependencies
370
+ ```
371
+
372
+ ### CI/CD
373
+
374
+ The project runs six GitHub Actions workflows:
375
+
376
+ | Workflow | Trigger | Purpose |
377
+ |---|---|---|
378
+ | `build.yml` | Push / PR | Lint, test with coverage, type-check, verify CEM manifest, verify API surface, build |
379
+ | `publish.yml` | Git tag `v*` | Version alignment check, test, build, publish to npm |
380
+ | `docs.yml` | Push to main | Build and deploy VitePress + TypeDoc docs to GitHub Pages |
381
+ | `audit.yml` | Schedule | Security audit of dependencies |
382
+ | `size-limit.yml` | Push / PR | Bundle size monitoring (main: 210 kB gzip, all chunks: 785 kB gzip) |
383
+ | `compat-check.yml` | Push / PR | Compatibility testing |
384
+
385
+ ### Testing
386
+
387
+ Tests use Vitest with both jsdom (unit) and Playwright (browser) environments:
388
+
389
+ ```bash
390
+ pnpm test:run # Run all tests once
391
+ pnpm test # Watch mode
392
+ pnpm test:coverage # With V8 coverage (text, HTML, LCOV)
184
393
  ```
185
394
 
395
+ Test coverage includes services, schemas, signals, controllers, utilities, layout algorithms, UI components, web workers, accessibility (vitest-axe), and integration tests.
396
+
397
+ ## Documentation
398
+
399
+ Full docs at **[ajkolean.github.io/xcode-graph](https://ajkolean.github.io/xcode-graph/)**
400
+
401
+ - [Getting Started](https://ajkolean.github.io/xcode-graph/guide/) — Installation, usage, data shape, theming, and color scheme
402
+ - [Swift Integration](https://ajkolean.github.io/xcode-graph/guide/swift-integration) — Embedding in a Swift server with SwiftNIO
403
+ - [Component API](https://ajkolean.github.io/xcode-graph/reference/component-api) — Properties, methods, events, CSS custom properties
404
+ - [Data Types](https://ajkolean.github.io/xcode-graph/reference/data-types) — GraphNode, GraphEdge, enums, and all type definitions
405
+ - [Layout Configuration](https://ajkolean.github.io/xcode-graph/reference/layout-configuration) — ELK & D3-force parameters and lifecycle hooks
406
+ - [API Reference](https://ajkolean.github.io/xcode-graph/api/) — Full TypeDoc reference (100+ exported functions, classes, and types)
407
+
186
408
  ## License
187
409
 
188
410
  [MIT](LICENSE) &copy; Andy Kolean