@ankhorage/zora 20.1.6 → 20.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.d.ts +13 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.js +71 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.d.ts +87 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js +132 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/GraphView.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.d.ts +7 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.js +59 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.d.ts +7 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.js +32 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphController.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.d.ts +22 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.js +41 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts +30 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js +222 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createRenderableGraphElements.d.ts +5 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createRenderableGraphElements.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createRenderableGraphElements.js +51 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/createRenderableGraphElements.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/fitGraphViewport.d.ts +5 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/fitGraphViewport.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/fitGraphViewport.js +18 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/fitGraphViewport.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/readGraphRenderedNodes.d.ts +5 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/readGraphRenderedNodes.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/readGraphRenderedNodes.js +14 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/readGraphRenderedNodes.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/runGraphLayout.d.ts +14 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/runGraphLayout.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/runGraphLayout.js +34 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/runGraphLayout.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/scheduleGraphFrame.d.ts +3 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/scheduleGraphFrame.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/scheduleGraphFrame.js +10 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/scheduleGraphFrame.js.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/syncGraphElements.d.ts +5 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/syncGraphElements.d.ts.map +1 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/syncGraphElements.js +12 -0
- package/dist/features/graph-view/adapters/inbound/web-artifact/syncGraphElements.js.map +1 -0
- package/dist/features/web-component-artifact/application/use-cases/materializeWebComponentArtifactAsync.d.ts.map +1 -1
- package/dist/features/web-component-artifact/application/use-cases/materializeWebComponentArtifactAsync.js +25 -10
- package/dist/features/web-component-artifact/application/use-cases/materializeWebComponentArtifactAsync.js.map +1 -1
- package/package.json +6 -4
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphNodeOverlay.tsx +142 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/GraphView.tsx +293 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/bindGraphEvents.ts +102 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphController.ts +38 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphResizeObserver.ts +80 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createGraphRuntime.ts +301 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createRenderableGraphElements.test.ts +49 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/createRenderableGraphElements.ts +72 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/fitGraphViewport.ts +20 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/readGraphRenderedNodes.ts +20 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/runGraphLayout.ts +53 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/scheduleGraphFrame.ts +13 -0
- package/src/features/graph-view/adapters/inbound/web-artifact/syncGraphElements.ts +19 -0
- package/src/features/web-component-artifact/application/use-cases/materializeWebComponentArtifactAsync.test.ts +47 -31
- package/src/features/web-component-artifact/application/use-cases/materializeWebComponentArtifactAsync.ts +47 -11
- package/src/types/cytoscape-elk.d.ts +4 -0
- package/web-dist/graph-view/GraphView.d.ts +87 -0
- package/web-dist/graph-view/GraphView.js +123308 -0
- package/web-dist/graph-view/artifact.json +7 -0
- package/web-dist/tree-view/artifact.json +7 -0
|
@@ -3,39 +3,55 @@ import { expect, test } from 'bun:test';
|
|
|
3
3
|
import type { WebComponentArtifactFileSystemPort } from '../ports/outbound/WebComponentArtifactFileSystemPort';
|
|
4
4
|
import { materializeWebComponentArtifactAsync } from './materializeWebComponentArtifactAsync';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
for (const artifact of [
|
|
7
|
+
{ component: 'tree-view', outputName: 'TreeView' },
|
|
8
|
+
{ component: 'graph-view', outputName: 'GraphView' },
|
|
9
|
+
] as const) {
|
|
10
|
+
test(`materializes packaged ${artifact.component} without source ownership transfer`, async () => {
|
|
11
|
+
const packageRoot = '/package';
|
|
12
|
+
const outputDirectory = `/consumer/src/generated/zora/${artifact.component}`;
|
|
13
|
+
const writes = new Map<string, string>();
|
|
14
|
+
const sourceDirectory = `${packageRoot}/web-dist/${artifact.component}`;
|
|
15
|
+
const sources = new Map<string, string>([
|
|
16
|
+
[
|
|
17
|
+
`${sourceDirectory}/artifact.json`,
|
|
18
|
+
JSON.stringify({
|
|
19
|
+
component: artifact.component,
|
|
20
|
+
files: [`${artifact.outputName}.js`, `${artifact.outputName}.d.ts`],
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
23
|
+
[`${sourceDirectory}/${artifact.outputName}.js`, 'export const component = 1;\n'],
|
|
24
|
+
[
|
|
25
|
+
`${sourceDirectory}/${artifact.outputName}.d.ts`,
|
|
26
|
+
'export declare const component: unknown;\n',
|
|
27
|
+
],
|
|
28
|
+
]);
|
|
29
|
+
const fileSystem = createFakeFileSystem(sources, writes);
|
|
15
30
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
31
|
+
const result = await materializeWebComponentArtifactAsync(
|
|
32
|
+
{
|
|
33
|
+
component: artifact.component,
|
|
34
|
+
outputDirectory,
|
|
35
|
+
packageRoot,
|
|
36
|
+
packageVersion: '1.2.3',
|
|
37
|
+
},
|
|
38
|
+
fileSystem,
|
|
39
|
+
);
|
|
25
40
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
41
|
+
expect(result.platform).toBe('web');
|
|
42
|
+
expect(result.createdFiles).toEqual([
|
|
43
|
+
`${outputDirectory}/${artifact.outputName}.js`,
|
|
44
|
+
`${outputDirectory}/${artifact.outputName}.d.ts`,
|
|
45
|
+
`${outputDirectory}/zora-artifact.json`,
|
|
46
|
+
]);
|
|
47
|
+
expect(writes.get(`${outputDirectory}/${artifact.outputName}.js`)).toStartWith(
|
|
48
|
+
'// Generated by @ankhorage/zora v1.2.3. Do not edit manually.',
|
|
49
|
+
);
|
|
50
|
+
expect(writes.get(`${outputDirectory}/zora-artifact.json`)).toContain(
|
|
51
|
+
'"owner": "@ankhorage/zora"',
|
|
52
|
+
);
|
|
53
|
+
});
|
|
54
|
+
}
|
|
39
55
|
|
|
40
56
|
test('rejects unsupported web components explicitly', async () => {
|
|
41
57
|
const fileSystem = createFakeFileSystem(new Map(), new Map());
|
|
@@ -19,8 +19,12 @@ export async function materializeWebComponentArtifactAsync(
|
|
|
19
19
|
input: MaterializeWebComponentArtifactInput,
|
|
20
20
|
fileSystem: WebComponentArtifactFileSystemPort,
|
|
21
21
|
): Promise<MaterializeWebComponentArtifactResult> {
|
|
22
|
-
const
|
|
23
|
-
const
|
|
22
|
+
const sourceDirectory = fileSystem.joinPath(input.packageRoot, 'web-dist', input.component);
|
|
23
|
+
const artifact = await readWebArtifactDefinitionAsync(
|
|
24
|
+
sourceDirectory,
|
|
25
|
+
input.component,
|
|
26
|
+
fileSystem,
|
|
27
|
+
);
|
|
24
28
|
await fileSystem.ensureDirectoryAsync(input.outputDirectory);
|
|
25
29
|
|
|
26
30
|
const createdFiles = await Promise.all(
|
|
@@ -61,20 +65,52 @@ export async function materializeWebComponentArtifactAsync(
|
|
|
61
65
|
}
|
|
62
66
|
|
|
63
67
|
interface WebArtifactDefinition {
|
|
64
|
-
readonly
|
|
68
|
+
readonly component: string;
|
|
65
69
|
readonly files: readonly string[];
|
|
66
70
|
}
|
|
67
71
|
|
|
68
|
-
/***
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
/*** Read one packaged artifact manifest so new web components require no CLI branching. */
|
|
73
|
+
async function readWebArtifactDefinitionAsync(
|
|
74
|
+
sourceDirectory: string,
|
|
75
|
+
component: string,
|
|
76
|
+
fileSystem: WebComponentArtifactFileSystemPort,
|
|
77
|
+
): Promise<WebArtifactDefinition> {
|
|
78
|
+
const manifestPath = fileSystem.joinPath(sourceDirectory, 'artifact.json');
|
|
79
|
+
const manifestSource = await readWebArtifactManifestSourceAsync(
|
|
80
|
+
manifestPath,
|
|
81
|
+
component,
|
|
82
|
+
fileSystem,
|
|
83
|
+
);
|
|
84
|
+
const parsed = JSON.parse(manifestSource) as {
|
|
85
|
+
readonly component?: unknown;
|
|
86
|
+
readonly files?: unknown;
|
|
87
|
+
};
|
|
88
|
+
if (
|
|
89
|
+
parsed.component !== component ||
|
|
90
|
+
!Array.isArray(parsed.files) ||
|
|
91
|
+
parsed.files.length === 0 ||
|
|
92
|
+
!parsed.files.every((fileName) => typeof fileName === 'string' && fileName.length > 0)
|
|
93
|
+
) {
|
|
94
|
+
throw new Error(`Invalid ZORA web artifact manifest: ${component}`);
|
|
75
95
|
}
|
|
76
96
|
|
|
77
|
-
|
|
97
|
+
return {
|
|
98
|
+
component,
|
|
99
|
+
files: parsed.files,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/*** Read an artifact manifest and translate missing packages into the CLI-facing error. */
|
|
104
|
+
async function readWebArtifactManifestSourceAsync(
|
|
105
|
+
manifestPath: string,
|
|
106
|
+
component: string,
|
|
107
|
+
fileSystem: WebComponentArtifactFileSystemPort,
|
|
108
|
+
): Promise<string> {
|
|
109
|
+
try {
|
|
110
|
+
return await fileSystem.readTextFileAsync(manifestPath);
|
|
111
|
+
} catch {
|
|
112
|
+
throw new Error(`Unsupported ZORA web component: ${component}`);
|
|
113
|
+
}
|
|
78
114
|
}
|
|
79
115
|
|
|
80
116
|
/*** Add a generated-file marker without changing the compiled artifact semantics. */
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type GraphViewLayoutName = 'breadthfirst' | 'circle' | 'concentric' | 'elk' | 'grid';
|
|
3
|
+
export type GraphViewElementEventType = 'press' | 'double-press' | 'select' | 'unselect' | 'pointer-enter' | 'pointer-leave';
|
|
4
|
+
export interface GraphViewNode {
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly label?: string;
|
|
7
|
+
readonly parentId?: string;
|
|
8
|
+
readonly classes?: string;
|
|
9
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
10
|
+
}
|
|
11
|
+
export interface GraphViewEdge {
|
|
12
|
+
readonly id?: string;
|
|
13
|
+
readonly source: string;
|
|
14
|
+
readonly target: string;
|
|
15
|
+
readonly classes?: string;
|
|
16
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
17
|
+
}
|
|
18
|
+
export interface GraphViewStyleRule {
|
|
19
|
+
readonly selector: string;
|
|
20
|
+
readonly style: Readonly<Record<string, unknown>>;
|
|
21
|
+
}
|
|
22
|
+
export interface GraphViewPoint {
|
|
23
|
+
readonly x: number;
|
|
24
|
+
readonly y: number;
|
|
25
|
+
}
|
|
26
|
+
export interface GraphViewSize {
|
|
27
|
+
readonly width: number;
|
|
28
|
+
readonly height: number;
|
|
29
|
+
}
|
|
30
|
+
export interface GraphViewNodeRenderContext {
|
|
31
|
+
readonly hovered: boolean;
|
|
32
|
+
readonly node: GraphViewNode;
|
|
33
|
+
readonly selected: boolean;
|
|
34
|
+
readonly zoom: number;
|
|
35
|
+
}
|
|
36
|
+
export interface GraphViewRenderedNode {
|
|
37
|
+
readonly hovered: boolean;
|
|
38
|
+
readonly id: string;
|
|
39
|
+
readonly position: GraphViewPoint;
|
|
40
|
+
readonly selected: boolean;
|
|
41
|
+
readonly zoom: number;
|
|
42
|
+
}
|
|
43
|
+
export interface GraphViewViewport {
|
|
44
|
+
readonly zoom: number;
|
|
45
|
+
readonly pan: GraphViewPoint;
|
|
46
|
+
}
|
|
47
|
+
export interface GraphViewFitOptions {
|
|
48
|
+
readonly nodeIds?: readonly string[];
|
|
49
|
+
readonly padding?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface GraphViewElementEvent {
|
|
52
|
+
readonly id: string;
|
|
53
|
+
readonly type: GraphViewElementEventType;
|
|
54
|
+
}
|
|
55
|
+
export interface GraphViewController {
|
|
56
|
+
fit(options?: GraphViewFitOptions): void;
|
|
57
|
+
getViewport(): GraphViewViewport;
|
|
58
|
+
setPan(pan: GraphViewPoint): void;
|
|
59
|
+
setZoom(zoom: number): void;
|
|
60
|
+
zoomBy(factor: number): void;
|
|
61
|
+
}
|
|
62
|
+
export interface GraphViewProps {
|
|
63
|
+
readonly nodes: readonly GraphViewNode[];
|
|
64
|
+
readonly edges: readonly GraphViewEdge[];
|
|
65
|
+
readonly layout?: GraphViewLayoutName;
|
|
66
|
+
readonly layoutOptions?: Readonly<Record<string, unknown>>;
|
|
67
|
+
readonly spacingFactor?: number;
|
|
68
|
+
readonly styleRules?: readonly GraphViewStyleRule[];
|
|
69
|
+
readonly selectedNodeIds?: readonly string[];
|
|
70
|
+
readonly renderNode?: (context: GraphViewNodeRenderContext) => React.ReactNode;
|
|
71
|
+
readonly getNodeSize?: (node: GraphViewNode) => GraphViewSize | undefined;
|
|
72
|
+
readonly fitPadding?: number;
|
|
73
|
+
readonly minZoom?: number;
|
|
74
|
+
readonly maxZoom?: number;
|
|
75
|
+
readonly className?: string;
|
|
76
|
+
readonly style?: React.CSSProperties;
|
|
77
|
+
readonly ariaLabel?: string;
|
|
78
|
+
readonly onReady?: (controller: GraphViewController) => void;
|
|
79
|
+
readonly onLayoutComplete?: (controller: GraphViewController) => void;
|
|
80
|
+
readonly onNodeEvent?: (event: GraphViewElementEvent) => void;
|
|
81
|
+
readonly onEdgeEvent?: (event: GraphViewElementEvent) => void;
|
|
82
|
+
readonly onViewportChange?: (viewport: GraphViewViewport) => void;
|
|
83
|
+
}
|
|
84
|
+
export type GraphViewCallbacks = Pick<GraphViewProps, 'onEdgeEvent' | 'onLayoutComplete' | 'onNodeEvent' | 'onReady' | 'onViewportChange'>;
|
|
85
|
+
/*** Render a browser graph while one runtime owns Cytoscape layout, viewport, and disposal. */
|
|
86
|
+
export declare function GraphView(props: GraphViewProps): React.JSX.Element;
|
|
87
|
+
//# sourceMappingURL=GraphView.d.ts.map
|