UNPKG

5.53 kBMarkdownView Raw
1# @stoplight/graphite
2[![Maintainability](https://api.codeclimate.com/v1/badges/ac453dbde4e365fe9cce/maintainability)](https://codeclimate.com/repos/5bd8e4484426590257001c75) [![Test Coverage](https://api.codeclimate.com/v1/badges/ac453dbde4e365fe9cce/test_coverage)](https://codeclimate.com/repos/5bd8e4484426590257001c75)
3
4<!-- BADGES -->
5
6Nodes'n things.
7
8- Explore the components: [Storybook](https://stoplightio.github.io/graphite)
9- View the changelog: [Releases](https://github.com/stoplightio/graphite/releases)
10
11## Installation
12
13Supported in modern browsers and node.
14
15```bash
16# latest stable
17yarn add @stoplight/graphite
18```
19
20## Usage
21
22Note, this is not all implemented, but rather an example of what it might look like.
23
24```ts
25import {
26 Graphite,
27 FilesystemPlugin,
28 JsonPlugin,
29 YamlPlugin,
30 Oas2Plugin
31} from "@stoplight/graphite";
32
33const graphite = Graphite();
34
35graphite.registerPlugins(
36 FilesystemSource(),
37 JsonPlugin(),
38 YamlPlugin(),
39 Oas2Plugin()
40);
41
42// Mirror two Graphite instances. The mirroredGraphite instance has no plugins, and simply applies the results of the graphite instance.
43const mirroredGraphite = Graphite();
44graphite.on("did_patch", mirroredGraphite.applyPatch);
45
46// Add a single SourceNode of type file
47const n = graphite.addSourceNode({
48 type: FilesystemPlugin.File,
49 path: "/foo.json"
50});
51
52// Queue up a read task for that node
53n.read();
54
55// Wait until all processing is done
56await graphite.tasksProcessed();
57
58// The two graphs should be identical, ids and all.
59// Note, the mirroredGraph did NO work - all the file reading, parsing, etc, was done by the plugins in the main graphite instance.
60expect(graphite.dehydrate()).toEqual(mirroredGraphite.dehydrate());
61```
62
63## Concepts
64
65### Graph
66
67- Holds nodes and edges.
68- Exposes methods to `add` and `remove` nodes/edges.
69- Responsible for managing node/edge lifecycle.
70
71#### Nodes
72
73- They hold data.
74- There are three node categories (described below): `source`, `source_map`, and `virtual`.
75
76#### Edges
77
78- They represent relationships between nodes.
79
80### Graphite
81
82- Manages a single graph instance.
83- Exposes `applyPatch` method.
84- Emits events as patches are processed.
85- Exposes convenience methods for common patterns, such as `addSourceNode`, that simply build and a patch or task and call `applyPatch` or `queueTask`.
86- Manages tasks.
87
88### Mutations
89
90- ALL changes, both internal and external, pass through the `graphite.applyPatch` method.
91
92#### JsonPatch
93
94- A group of `JsonOperations`.
95
96#### GraphPatch
97
98- A group of `JsonOperations`, and their inverse. This is similar to the concept of a "transaction".
99- If one operation fails, they all fail, and a rollback is attempted.
100
101#### GraphTask
102
103- Describes a single change to be made to the graph.
104- Any operations that cannot be accomplished via `JsonPatch` must be queued up via a `GraphTask`.
105- Examples include `add_node`, `read_node`, `write_node`, `parse_node`, `compute_node_source_map`.
106- Plugins can define their own tasks, such as `oas2_lint_node`.
107- The result of a `GraphTask` must always be a `GraphPatch`.
108- When a task is run, the `GraphPatch` it returns is applied to the graph.
109
110#### Scheduler
111
112- Manages one or more task queues.
113- We will at the very least have `high` and `low` priority queues.
114- Tasks such as `add_node` and `read_node` will go into a `high` priority queue.
115- Tasks such as `oas2_lint_node` and `resolve_node` will go into a `low` priority queue.
116
117#### Notifier
118
119- Manages events like a boss.
120
121### Sources
122
123#### SourceNode
124
125- Source nodes are the only node category
126- Exposes 4 primary properties - `original`, `raw`, `parsed` (TODO), and `isDirty`.
127- Exposes 4 primary methods - `read`, `write`, `updateRaw`, and `updateParsed`.
128
129#### SourceSink
130
131- Responsible for reading data from some data source, and adding the appropriate source nodes.
132- Responsible for refreshing the `original` property of a `SourceNode` in response to `read_node` tasks.
133- Responsible for writing the `SourceNode` raw property back to the data source in response to `write_node` tasks.
134- Implements `ISourceReader` and/or `ISourceWriter`.
135
136#### SourceParser
137
138- Targets one or more `SourceNodes`.
139- Responsible for computing its `parsed` value when `raw` changes.
140- Responsible for computing its `raw` value when `parsed` changes.
141
142#### SourceMapNode
143
144- A specific type of node that is a child of a `SourceNode`.
145- Its `uri` points to a real location in the original source.
146- Its data property points to a value in its parent `SourceNode.parsed`, according to its `uri`.
147- Exposes an `update` method that queues a `GraphPatch` to update its source node parsed value.
148
149#### SourceTree
150
151- Defines a `ISourceTreeMap` that describes how a `SourceNode.parsed` value should be translated into `SourceMapNodes`.
152
153### VirtualNode
154
155- Anything that is not a `SourceNode` or `SourceTreeNode`
156- Examples: linting results, transformed http operation and http service nodes, etc
157
158## Contributing
159
1601. Clone repo.
1612. Create / checkout `feature/{name}`, `chore/{name}`, or `fix/{name}` branch.
1623. Install deps: `yarn`.
1634. Make your changes.
1645. Run tests: `yarn test.prod`.
1656. Stage relevant files to git.
1667. Commit: `yarn commit`. _NOTE: Commits that don't follow the [conventional](https://github.com/marionebl/commitlint/tree/master/%40commitlint/config-conventional) format will be rejected. `yarn commit` creates this format for you, or you can put it together manually and then do a regular `git commit`._
1678. Push: `git push`.
1689. Open PR targeting the `next` branch.