rocket-engine 0.0.2b1__py3-none-any.whl
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.
- rocket_engine/__init__.py +8 -0
- rocket_engine/__main__.py +12 -0
- rocket_engine/adapters/README.md +54 -0
- rocket_engine/adapters/__init__.py +7 -0
- rocket_engine/adapters/api.py +39 -0
- rocket_engine/adapters/base.py +46 -0
- rocket_engine/adapters/cace/__init__.py +163 -0
- rocket_engine/adapters/circulax/README.md +10 -0
- rocket_engine/adapters/circulax/__init__.py +112 -0
- rocket_engine/adapters/circulax/_driver.py +190 -0
- rocket_engine/adapters/circulax/adapter.py +538 -0
- rocket_engine/adapters/circulax/results.py +291 -0
- rocket_engine/adapters/cli/README.md +34 -0
- rocket_engine/adapters/cli/__init__.py +305 -0
- rocket_engine/adapters/connectivity/__init__.py +196 -0
- rocket_engine/adapters/connectivity/results.py +214 -0
- rocket_engine/adapters/cosim/README.md +9 -0
- rocket_engine/adapters/cosim/__init__.py +1390 -0
- rocket_engine/adapters/cosim/results.py +214 -0
- rocket_engine/adapters/devsim/__init__.py +171 -0
- rocket_engine/adapters/digital_flow/README.md +9 -0
- rocket_engine/adapters/digital_flow/__init__.py +1121 -0
- rocket_engine/adapters/digital_flow/results.py +227 -0
- rocket_engine/adapters/digital_flow/state.py +462 -0
- rocket_engine/adapters/drc/README.klayout.md +7 -0
- rocket_engine/adapters/drc/README.md +7 -0
- rocket_engine/adapters/drc/__init__.py +1 -0
- rocket_engine/adapters/drc/klayout.py +952 -0
- rocket_engine/adapters/drc/magic.py +287 -0
- rocket_engine/adapters/drc/results.py +184 -0
- rocket_engine/adapters/drc/results_kl.py +188 -0
- rocket_engine/adapters/elmer/__init__.py +163 -0
- rocket_engine/adapters/envelope.py +120 -0
- rocket_engine/adapters/equivalence/__init__.py +156 -0
- rocket_engine/adapters/errors.py +181 -0
- rocket_engine/adapters/extract_magic/README.md +15 -0
- rocket_engine/adapters/extract_magic/__init__.py +425 -0
- rocket_engine/adapters/extract_magic/results.py +209 -0
- rocket_engine/adapters/formal_sby/README.md +7 -0
- rocket_engine/adapters/formal_sby/__init__.py +773 -0
- rocket_engine/adapters/formal_sby/formal_edge.py +195 -0
- rocket_engine/adapters/formal_sby/results.py +185 -0
- rocket_engine/adapters/gdsfactory/__init__.py +194 -0
- rocket_engine/adapters/gdsfactory/_driver.py +459 -0
- rocket_engine/adapters/gdsfactory/adapter.py +609 -0
- rocket_engine/adapters/gdsfactory/results.py +181 -0
- rocket_engine/adapters/hdl_sim/README.md +7 -0
- rocket_engine/adapters/hdl_sim/__init__.py +369 -0
- rocket_engine/adapters/hdl_sim/ghdl.py +155 -0
- rocket_engine/adapters/hdl_sim/results.py +178 -0
- rocket_engine/adapters/hdl_sim/verilator.py +167 -0
- rocket_engine/adapters/http/README.md +15 -0
- rocket_engine/adapters/http/__init__.py +458 -0
- rocket_engine/adapters/http/events.py +63 -0
- rocket_engine/adapters/ipc/README.md +9 -0
- rocket_engine/adapters/ipc/__init__.py +111 -0
- rocket_engine/adapters/lvs_netgen/README.md +20 -0
- rocket_engine/adapters/lvs_netgen/__init__.py +889 -0
- rocket_engine/adapters/lvs_netgen/results.py +168 -0
- rocket_engine/adapters/mcp/README.md +19 -0
- rocket_engine/adapters/mcp/__init__.py +85 -0
- rocket_engine/adapters/mcp/api-schema.json +6107 -0
- rocket_engine/adapters/mcp/pull.py +246 -0
- rocket_engine/adapters/mcp/server.py +794 -0
- rocket_engine/adapters/meep/__init__.py +167 -0
- rocket_engine/adapters/meow/README.md +7 -0
- rocket_engine/adapters/meow/__init__.py +190 -0
- rocket_engine/adapters/meow/_driver.py +227 -0
- rocket_engine/adapters/meow/_envelope.py +108 -0
- rocket_engine/adapters/meow/adapter.py +491 -0
- rocket_engine/adapters/meow/results.py +218 -0
- rocket_engine/adapters/mutation/__init__.py +192 -0
- rocket_engine/adapters/ngspice/README.md +28 -0
- rocket_engine/adapters/ngspice/__init__.py +627 -0
- rocket_engine/adapters/ngspice/results.py +215 -0
- rocket_engine/adapters/postlayout/README.md +28 -0
- rocket_engine/adapters/postlayout/__init__.py +17 -0
- rocket_engine/adapters/postlayout/adapter.py +1062 -0
- rocket_engine/adapters/postlayout/results.py +330 -0
- rocket_engine/adapters/postlayout/translate.py +71 -0
- rocket_engine/adapters/profile.py +220 -0
- rocket_engine/adapters/sax/README.md +23 -0
- rocket_engine/adapters/sax/__init__.py +516 -0
- rocket_engine/adapters/sax/_driver.py +148 -0
- rocket_engine/adapters/sax/results.py +291 -0
- rocket_engine/adapters/stdio_console.py +1151 -0
- rocket_engine/adapters/syntax/README.md +5 -0
- rocket_engine/adapters/syntax/__init__.py +366 -0
- rocket_engine/adapters/syntax/results.py +181 -0
- rocket_engine/adapters/synth_yosys/README.md +7 -0
- rocket_engine/adapters/synth_yosys/__init__.py +655 -0
- rocket_engine/adapters/synth_yosys/amaranth.py +120 -0
- rocket_engine/adapters/synth_yosys/ghdl.py +128 -0
- rocket_engine/adapters/synth_yosys/results.py +173 -0
- rocket_engine/adapters/timing_sta/README.md +9 -0
- rocket_engine/adapters/timing_sta/__init__.py +726 -0
- rocket_engine/adapters/view_sync/__init__.py +185 -0
- rocket_engine/adapters/view_sync/results.py +189 -0
- rocket_engine/adapters/vlsir/__init__.py +142 -0
- rocket_engine/adapters/xschem/__init__.py +440 -0
- rocket_engine/adapters/xschem/deck.py +266 -0
- rocket_engine/clients/__init__.py +5 -0
- rocket_engine/clients/runtime.py +255 -0
- rocket_engine/composition.py +2279 -0
- rocket_engine/execution/README.md +30 -0
- rocket_engine/execution/__init__.py +150 -0
- rocket_engine/execution/apig/__init__.py +1 -0
- rocket_engine/execution/apig/pool.py +463 -0
- rocket_engine/execution/apig/submit.py +124 -0
- rocket_engine/execution/block_runs_scope.py +479 -0
- rocket_engine/execution/coalesce.py +414 -0
- rocket_engine/execution/console/__init__.py +1 -0
- rocket_engine/execution/console/apply_session.py +318 -0
- rocket_engine/execution/console/lifecycle.py +265 -0
- rocket_engine/execution/dispatch.py +205 -0
- rocket_engine/execution/errors.py +31 -0
- rocket_engine/execution/ports.py +797 -0
- rocket_engine/execution/pyexec/__init__.py +1 -0
- rocket_engine/execution/pyexec/apply_context.py +547 -0
- rocket_engine/execution/pyexec/approvals.py +173 -0
- rocket_engine/execution/pyexec/runner.py +404 -0
- rocket_engine/execution/pyexec/support.py +464 -0
- rocket_engine/execution/python_exec.py +897 -0
- rocket_engine/execution/queue.py +85 -0
- rocket_engine/execution/replay_safe.py +601 -0
- rocket_engine/execution/routing/__init__.py +1 -0
- rocket_engine/execution/routing/calls.py +364 -0
- rocket_engine/execution/routing/namespace.py +785 -0
- rocket_engine/execution/routing/ports.py +102 -0
- rocket_engine/execution/routing/tools.py +346 -0
- rocket_engine/execution/runner.py +311 -0
- rocket_engine/execution/runtime.py +1149 -0
- rocket_engine/execution/service.py +279 -0
- rocket_engine/execution/worker.py +464 -0
- rocket_engine/interfaces/README.md +26 -0
- rocket_engine/interfaces/__init__.py +58 -0
- rocket_engine/interfaces/apig_assets.py +407 -0
- rocket_engine/interfaces/celllink.py +461 -0
- rocket_engine/interfaces/documents.py +92 -0
- rocket_engine/interfaces/envelopes.py +131 -0
- rocket_engine/interfaces/errors.py +16 -0
- rocket_engine/interfaces/layout.py +410 -0
- rocket_engine/interfaces/layout_schema.yaml +278 -0
- rocket_engine/interfaces/paths.py +223 -0
- rocket_engine/interfaces/pdks.py +550 -0
- rocket_engine/interfaces/ports.py +72 -0
- rocket_engine/interfaces/references.py +115 -0
- rocket_engine/interfaces/refs.py +85 -0
- rocket_engine/interfaces/runparams.py +304 -0
- rocket_engine/interfaces/setup.py +552 -0
- rocket_engine/interfaces/setup_catalogue.yaml +243 -0
- rocket_engine/interfaces/setup_probes.py +66 -0
- rocket_engine/interfaces/vocabulary.py +58 -0
- rocket_engine/interfaces/yaml_dump.py +31 -0
- rocket_engine/library/README.md +22 -0
- rocket_engine/library/__init__.py +13 -0
- rocket_engine/library/apig_catalog.py +371 -0
- rocket_engine/library/catalog.py +185 -0
- rocket_engine/library/errors.py +16 -0
- rocket_engine/mutate/__init__.py +776 -0
- rocket_engine/mutate/operators.py +700 -0
- rocket_engine/ops/__init__.py +1 -0
- rocket_engine/ops/deferred.py +279 -0
- rocket_engine/ops/editors.py +404 -0
- rocket_engine/ops/evidence.py +194 -0
- rocket_engine/ops/gates.py +262 -0
- rocket_engine/ops/ports.py +76 -0
- rocket_engine/ops/queries.py +417 -0
- rocket_engine/ops/runs.py +553 -0
- rocket_engine/ops/submit.py +614 -0
- rocket_engine/project/README.md +27 -0
- rocket_engine/project/__init__.py +6 -0
- rocket_engine/project/canvas/__init__.py +55 -0
- rocket_engine/project/canvas/compile.py +109 -0
- rocket_engine/project/canvas/integrate.py +48 -0
- rocket_engine/project/canvas/schema.py +241 -0
- rocket_engine/project/canvas/templates.py +46 -0
- rocket_engine/project/canvas/validate.py +603 -0
- rocket_engine/project/edit/__init__.py +5 -0
- rocket_engine/project/edit/cas.py +87 -0
- rocket_engine/project/edit/transactions.py +282 -0
- rocket_engine/project/errors.py +16 -0
- rocket_engine/project/frontend13.py +685 -0
- rocket_engine/project/geometry/__init__.py +23 -0
- rocket_engine/project/geometry/ops.py +451 -0
- rocket_engine/project/geometry/snap.py +103 -0
- rocket_engine/project/ip/__init__.py +1 -0
- rocket_engine/project/ip/blocks.py +195 -0
- rocket_engine/project/ip/entry.schema.json +78 -0
- rocket_engine/project/ip/lifecycle.py +402 -0
- rocket_engine/project/ip/verbs.py +123 -0
- rocket_engine/project/layers/__init__.py +6 -0
- rocket_engine/project/layers/bindings.py +115 -0
- rocket_engine/project/layers/catalog.py +228 -0
- rocket_engine/project/layers/presets.py +43 -0
- rocket_engine/project/ledger/__init__.py +1 -0
- rocket_engine/project/ledger/docs.py +167 -0
- rocket_engine/project/ledger/entities.py +176 -0
- rocket_engine/project/ledger/events.py +29 -0
- rocket_engine/project/ledger/runs.py +257 -0
- rocket_engine/project/ledger/shared.py +174 -0
- rocket_engine/project/ledger/snapshots.py +385 -0
- rocket_engine/project/ledger/wires.py +552 -0
- rocket_engine/project/process/__init__.py +14 -0
- rocket_engine/project/process/model.py +193 -0
- rocket_engine/project/process/recipes.py +121 -0
- rocket_engine/project/schematic/__init__.py +1 -0
- rocket_engine/project/schematic/hierarchy.py +312 -0
- rocket_engine/project/schematic/instances.py +393 -0
- rocket_engine/project/schematic/sheets.py +198 -0
- rocket_engine/project/service.py +2941 -0
- rocket_engine/project/symbols/__init__.py +1 -0
- rocket_engine/project/symbols/cells.py +324 -0
- rocket_engine/project/symbols/linkage.py +356 -0
- rocket_engine/project/symbols/symbols.py +352 -0
- rocket_engine/project/templates/__init__.py +303 -0
- rocket_engine/project/templates/errors.py +25 -0
- rocket_engine/project/testbench/__init__.py +49 -0
- rocket_engine/project/testbench/blocks.py +619 -0
- rocket_engine/project/testbench/templates.py +134 -0
- rocket_engine/stores/README.md +12 -0
- rocket_engine/stores/__init__.py +6 -0
- rocket_engine/stores/ecs.py +1508 -0
- rocket_engine/stores/layers.py +1023 -0
- rocket_engine/stores/settings.py +1188 -0
- rocket_engine/stores/wireplace.py +1324 -0
- rocket_engine/workflows/README.md +18 -0
- rocket_engine/workflows/__init__.py +53 -0
- rocket_engine/workflows/capability_plan.py +102 -0
- rocket_engine/workflows/completion.py +228 -0
- rocket_engine/workflows/connectgraph.py +734 -0
- rocket_engine/workflows/connectgraph_emit.py +336 -0
- rocket_engine/workflows/gates.py +144 -0
- rocket_engine/workflows/photonic_wire.py +76 -0
- rocket_engine/workflows/stages.py +324 -0
- rocket_engine/workflows/viewsync.py +399 -0
- rocket_engine-0.0.2b1.dist-info/METADATA +200 -0
- rocket_engine-0.0.2b1.dist-info/RECORD +241 -0
- rocket_engine-0.0.2b1.dist-info/WHEEL +4 -0
- rocket_engine-0.0.2b1.dist-info/entry_points.txt +2 -0
- rocket_engine-0.0.2b1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,785 @@
|
|
|
1
|
+
"""Host-side console namespace over ProjectService verbs."""
|
|
2
|
+
|
|
3
|
+
import uuid
|
|
4
|
+
|
|
5
|
+
from ...library.errors import LibraryError
|
|
6
|
+
from ...project.errors import ProjectError
|
|
7
|
+
from .calls import admission_envelope
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ConsoleNamespace:
|
|
11
|
+
"""Host-side console namespace: tier-2 verbs through admission.
|
|
12
|
+
|
|
13
|
+
One thin wrapper per tier-2 verb, named identically to the
|
|
14
|
+
CRUD/MCP verbs and calling the matching ProjectService verb
|
|
15
|
+
with the same call shape the Engine uses (verb arguments, then
|
|
16
|
+
the envelope id plus identity text, revision bound by keyword).
|
|
17
|
+
Every wrapper mints an envelope id when the caller omits one,
|
|
18
|
+
builds the admission identity text over its arguments, and
|
|
19
|
+
lets admission judge: stale revisions conflict, resubmits
|
|
20
|
+
replay, and accepted mutations advance once with one
|
|
21
|
+
actor-attributed ledger record. ECS and wire verbs fail loudly
|
|
22
|
+
until their peer patches land; place_cell needs a catalogue.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
project: Project port serving the public admission verbs
|
|
26
|
+
(ProjectService serves).
|
|
27
|
+
catalog: Component catalogue place_cell resolves through,
|
|
28
|
+
or None when cell placement stays unwired.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
def __init__(self, project, catalog=None):
|
|
32
|
+
self._project = project
|
|
33
|
+
self._catalog = catalog
|
|
34
|
+
|
|
35
|
+
def _admit(self, verb, arguments, request_id, expected_revision):
|
|
36
|
+
"""Envelope id plus identity text for one verb call."""
|
|
37
|
+
rid = request_id or uuid.uuid4().hex
|
|
38
|
+
payload = dict(arguments)
|
|
39
|
+
if expected_revision is not None:
|
|
40
|
+
payload["expected_revision"] = expected_revision
|
|
41
|
+
return rid, admission_envelope(verb, payload)
|
|
42
|
+
|
|
43
|
+
def _wired(self, verb, owner):
|
|
44
|
+
"""One ECS/wire project verb, or loud pre-patch refusal."""
|
|
45
|
+
method = getattr(self._project, verb, None)
|
|
46
|
+
if method is None:
|
|
47
|
+
raise ProjectError(
|
|
48
|
+
"unsupported_operation",
|
|
49
|
+
f"Console tier-2 verb {verb!r} needs the {owner} "
|
|
50
|
+
"wiring, which is not applied yet.",
|
|
51
|
+
)
|
|
52
|
+
return method
|
|
53
|
+
|
|
54
|
+
def write_doc(self, path, content, request_id=None,
|
|
55
|
+
expected_revision=None):
|
|
56
|
+
"""Write one document through admission.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
path: Document path to create or overwrite.
|
|
60
|
+
content: UTF-8 text to store.
|
|
61
|
+
request_id: Client envelope id; resubmitting the
|
|
62
|
+
identical call returns the identical response
|
|
63
|
+
without advancing.
|
|
64
|
+
expected_revision: Revision the writer read.
|
|
65
|
+
|
|
66
|
+
Returns:
|
|
67
|
+
Mutation mapping with path, revision transition, new
|
|
68
|
+
head, actor, diff summary, rewind handle, the
|
|
69
|
+
appended record, cursor, and request id.
|
|
70
|
+
|
|
71
|
+
Raises:
|
|
72
|
+
ProjectError: request_conflict for a reused id with
|
|
73
|
+
new arguments; invalid_path or path_escape for a
|
|
74
|
+
bad path; invalid_command for non-text content;
|
|
75
|
+
revision_conflict for a stale head.
|
|
76
|
+
|
|
77
|
+
Caution: Every accepted write advances the head — a
|
|
78
|
+
second writer at the old head fails instead of
|
|
79
|
+
merging.
|
|
80
|
+
"""
|
|
81
|
+
rid, text = self._admit(
|
|
82
|
+
"write_doc", {"path": path, "content": content},
|
|
83
|
+
request_id, expected_revision,
|
|
84
|
+
)
|
|
85
|
+
return self._project.write_doc(
|
|
86
|
+
path, content, rid, text,
|
|
87
|
+
expected_revision=expected_revision,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def delete_doc(self, path, request_id=None, expected_revision=None):
|
|
91
|
+
"""Delete one document through admission.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
path: Document path to delete.
|
|
95
|
+
request_id: Client envelope id for idempotent replay.
|
|
96
|
+
expected_revision: Revision the writer read.
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
Mutation mapping with path, revision transition, new
|
|
100
|
+
head, actor, diff summary, rewind handle, the
|
|
101
|
+
appended record, cursor, and request id.
|
|
102
|
+
|
|
103
|
+
Raises:
|
|
104
|
+
ProjectError: request_conflict for a reused id with
|
|
105
|
+
new arguments; invalid_path or path_escape for a
|
|
106
|
+
bad path; unknown_document for a missing document;
|
|
107
|
+
revision_conflict for a stale head.
|
|
108
|
+
|
|
109
|
+
Caution: Deleting advances the head like any mutation —
|
|
110
|
+
stale writers fail instead of merging.
|
|
111
|
+
"""
|
|
112
|
+
rid, text = self._admit(
|
|
113
|
+
"delete_doc", {"path": path}, request_id,
|
|
114
|
+
expected_revision,
|
|
115
|
+
)
|
|
116
|
+
return self._project.delete_doc(
|
|
117
|
+
path, rid, text, expected_revision=expected_revision
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
def apply_mutations(self, mutations, request_id=None,
|
|
121
|
+
expected_revision=None):
|
|
122
|
+
"""Apply a batch atomically under one new head.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
mutations: Non-empty list of write/delete mappings.
|
|
126
|
+
request_id: Client envelope id for idempotent replay.
|
|
127
|
+
expected_revision: Revision the writer read.
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
Mutation mapping with revision transition, new head,
|
|
131
|
+
actor, joined diff summary, rewind handle, the
|
|
132
|
+
single appended record, per-mutation results,
|
|
133
|
+
cursor, and request id.
|
|
134
|
+
|
|
135
|
+
Raises:
|
|
136
|
+
ProjectError: request_conflict for a reused id with
|
|
137
|
+
new arguments; invalid_command for a malformed
|
|
138
|
+
batch; unknown_document for a delete of a missing
|
|
139
|
+
document; revision_conflict for a stale head.
|
|
140
|
+
|
|
141
|
+
Caution: All-or-nothing means one head for the whole
|
|
142
|
+
batch — a half-landed batch is a bug, never a state.
|
|
143
|
+
"""
|
|
144
|
+
rid, text = self._admit(
|
|
145
|
+
"apply_mutations", {"mutations": mutations}, request_id,
|
|
146
|
+
expected_revision,
|
|
147
|
+
)
|
|
148
|
+
return self._project.apply_mutations(
|
|
149
|
+
mutations, rid, text, expected_revision=expected_revision
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
def place_cell(self, cell, request_id=None, expected_revision=None,
|
|
153
|
+
pdk=None, instance_id=None, params=None,
|
|
154
|
+
connections=None):
|
|
155
|
+
"""Place a catalogue cell through batch admission.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
cell: Catalogue cell name.
|
|
159
|
+
request_id: Client envelope id for idempotent replay.
|
|
160
|
+
expected_revision: Revision the writer read.
|
|
161
|
+
pdk: PDK label disambiguating same-named cells.
|
|
162
|
+
instance_id: Instance name; derived when omitted.
|
|
163
|
+
params: Override values for the cell defaults.
|
|
164
|
+
connections: Connection mappings over cell ports.
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Mutation mapping with the revision transition, new
|
|
168
|
+
head, actor, record, and request id.
|
|
169
|
+
|
|
170
|
+
Raises:
|
|
171
|
+
ProjectError: unsupported_operation without a
|
|
172
|
+
catalogue; unknown_cell, ambiguous_cell,
|
|
173
|
+
unknown_param, incompatible_port, or
|
|
174
|
+
instance_exists for a bad placement (catalogue
|
|
175
|
+
codes surface unchanged); revision_conflict for
|
|
176
|
+
a stale head; request_conflict for a reused id
|
|
177
|
+
with new arguments.
|
|
178
|
+
"""
|
|
179
|
+
if self._catalog is None:
|
|
180
|
+
raise ProjectError(
|
|
181
|
+
"unsupported_operation",
|
|
182
|
+
"place_cell needs a catalogue; this namespace was "
|
|
183
|
+
"built without one.",
|
|
184
|
+
)
|
|
185
|
+
try:
|
|
186
|
+
return self._catalog.place_cell(
|
|
187
|
+
self._project, cell, request_id or uuid.uuid4().hex,
|
|
188
|
+
expected_revision=expected_revision, pdk=pdk,
|
|
189
|
+
instance_id=instance_id, params=params,
|
|
190
|
+
connections=connections,
|
|
191
|
+
)
|
|
192
|
+
except LibraryError as exc:
|
|
193
|
+
raise ProjectError(exc.code, str(exc)) from exc
|
|
194
|
+
|
|
195
|
+
def create_entity(self, kind="", components=None, request_id=None,
|
|
196
|
+
expected_revision=None):
|
|
197
|
+
"""Create one entity with an engine-minted id.
|
|
198
|
+
|
|
199
|
+
Args:
|
|
200
|
+
kind: Kind label carried beside the components.
|
|
201
|
+
components: Optional initial component mapping.
|
|
202
|
+
request_id: Client envelope id for idempotent replay.
|
|
203
|
+
expected_revision: Revision the writer read.
|
|
204
|
+
|
|
205
|
+
Returns:
|
|
206
|
+
Mutation mapping with the minted entity, kind, storage
|
|
207
|
+
path, revision transition, new head, actor, diff
|
|
208
|
+
summary, rewind handle, the entity_created record,
|
|
209
|
+
cursor, and request id.
|
|
210
|
+
|
|
211
|
+
Raises:
|
|
212
|
+
ProjectError: unsupported_operation until the
|
|
213
|
+
ENGINE-ECS wiring lands; request_conflict for a
|
|
214
|
+
reused id with new arguments; invalid_kind,
|
|
215
|
+
invalid_component, or invalid_data for malformed
|
|
216
|
+
parts; revision_conflict for a stale head.
|
|
217
|
+
|
|
218
|
+
Caution: Every accepted create advances the head — a
|
|
219
|
+
second writer at the old head fails instead of
|
|
220
|
+
merging.
|
|
221
|
+
"""
|
|
222
|
+
arguments = {"kind": kind}
|
|
223
|
+
if components is not None:
|
|
224
|
+
arguments["components"] = components
|
|
225
|
+
rid, text = self._admit(
|
|
226
|
+
"create_entity", arguments, request_id, expected_revision
|
|
227
|
+
)
|
|
228
|
+
return self._wired("create_entity", "ENGINE-ECS")(
|
|
229
|
+
rid, text, kind=kind, components=components,
|
|
230
|
+
expected_revision=expected_revision,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
def set_component(self, entity, component, data, request_id=None,
|
|
234
|
+
expected_revision=None,
|
|
235
|
+
expected_entity_revision=None):
|
|
236
|
+
"""Upsert one component payload through admission.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
entity: Entity id holding the component.
|
|
240
|
+
component: Component name to write.
|
|
241
|
+
data: JSON payload to store.
|
|
242
|
+
request_id: Client envelope id for idempotent replay.
|
|
243
|
+
expected_revision: Revision the writer read.
|
|
244
|
+
expected_entity_revision: Entity revision the writer
|
|
245
|
+
read (ENTITY-CAS).
|
|
246
|
+
|
|
247
|
+
Returns:
|
|
248
|
+
Mutation mapping with entity, component, canonical
|
|
249
|
+
address, storage path, revision transition, new
|
|
250
|
+
head, actor, diff summary, rewind handle, the
|
|
251
|
+
component_changed record, cursor, and request id.
|
|
252
|
+
|
|
253
|
+
Raises:
|
|
254
|
+
ProjectError: unsupported_operation until the
|
|
255
|
+
ENGINE-ECS wiring lands; unknown_entity for a
|
|
256
|
+
missing entity; backfill_readonly for a
|
|
257
|
+
backfilled id; revision_conflict for a stale
|
|
258
|
+
head; request_conflict for a reused id with new
|
|
259
|
+
arguments.
|
|
260
|
+
|
|
261
|
+
Caution: Every accepted write advances the head — a
|
|
262
|
+
second writer at the old head fails instead of
|
|
263
|
+
merging.
|
|
264
|
+
"""
|
|
265
|
+
arguments = {"entity": entity, "component": component, "data": data}
|
|
266
|
+
if expected_entity_revision is not None:
|
|
267
|
+
arguments["expected_entity_revision"] = expected_entity_revision
|
|
268
|
+
rid, text = self._admit(
|
|
269
|
+
"set_component", arguments, request_id, expected_revision,
|
|
270
|
+
)
|
|
271
|
+
return self._wired("set_component", "ENGINE-ECS")(
|
|
272
|
+
entity, component, data, rid, text,
|
|
273
|
+
expected_revision=expected_revision,
|
|
274
|
+
expected_entity_revision=expected_entity_revision,
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
def attach_component(self, entity, component, data, request_id=None,
|
|
278
|
+
expected_revision=None,
|
|
279
|
+
expected_entity_revision=None):
|
|
280
|
+
"""Attach one new component through admission.
|
|
281
|
+
|
|
282
|
+
Args:
|
|
283
|
+
entity: Entity id holding the component.
|
|
284
|
+
component: Component name to attach.
|
|
285
|
+
data: JSON payload to store.
|
|
286
|
+
request_id: Client envelope id for idempotent replay.
|
|
287
|
+
expected_revision: Revision the writer read.
|
|
288
|
+
expected_entity_revision: Entity revision the writer
|
|
289
|
+
read (ENTITY-CAS).
|
|
290
|
+
|
|
291
|
+
Returns:
|
|
292
|
+
Mutation mapping with entity, component, canonical
|
|
293
|
+
address, storage path, revision transition, new
|
|
294
|
+
head, actor, diff summary, rewind handle, the
|
|
295
|
+
component_changed record, cursor, and request id.
|
|
296
|
+
|
|
297
|
+
Raises:
|
|
298
|
+
ProjectError: unsupported_operation until the
|
|
299
|
+
ENGINE-ECS wiring lands; component_exists when
|
|
300
|
+
the component already lives on the entity;
|
|
301
|
+
unknown_entity for a missing entity;
|
|
302
|
+
revision_conflict for a stale head.
|
|
303
|
+
|
|
304
|
+
Caution: Every accepted attach advances the head — a
|
|
305
|
+
second writer at the old head fails instead of
|
|
306
|
+
merging.
|
|
307
|
+
"""
|
|
308
|
+
arguments = {"entity": entity, "component": component, "data": data}
|
|
309
|
+
if expected_entity_revision is not None:
|
|
310
|
+
arguments["expected_entity_revision"] = expected_entity_revision
|
|
311
|
+
rid, text = self._admit(
|
|
312
|
+
"attach_component", arguments, request_id, expected_revision,
|
|
313
|
+
)
|
|
314
|
+
return self._wired("attach_component", "ENGINE-ECS")(
|
|
315
|
+
entity, component, data, rid, text,
|
|
316
|
+
expected_revision=expected_revision,
|
|
317
|
+
expected_entity_revision=expected_entity_revision,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
def detach_component(self, entity, component, request_id=None,
|
|
321
|
+
expected_revision=None,
|
|
322
|
+
expected_entity_revision=None):
|
|
323
|
+
"""Detach one component through admission.
|
|
324
|
+
|
|
325
|
+
Args:
|
|
326
|
+
entity: Entity id holding the component.
|
|
327
|
+
component: Component name to remove.
|
|
328
|
+
request_id: Client envelope id for idempotent replay.
|
|
329
|
+
expected_revision: Revision the writer read.
|
|
330
|
+
expected_entity_revision: Entity revision the writer
|
|
331
|
+
read (ENTITY-CAS).
|
|
332
|
+
|
|
333
|
+
Returns:
|
|
334
|
+
Mutation mapping with entity, component, canonical
|
|
335
|
+
address, storage path, revision transition, new
|
|
336
|
+
head, actor, diff summary, rewind handle, the
|
|
337
|
+
component_changed record, cursor, and request id.
|
|
338
|
+
|
|
339
|
+
Raises:
|
|
340
|
+
ProjectError: unsupported_operation until the
|
|
341
|
+
ENGINE-ECS wiring lands; unknown_component for a
|
|
342
|
+
missing component; revision_conflict for a stale
|
|
343
|
+
head; request_conflict for a reused id with new
|
|
344
|
+
arguments.
|
|
345
|
+
|
|
346
|
+
Caution: Every accepted detach advances the head — a
|
|
347
|
+
second writer at the old head fails instead of
|
|
348
|
+
merging.
|
|
349
|
+
"""
|
|
350
|
+
arguments = {"entity": entity, "component": component}
|
|
351
|
+
if expected_entity_revision is not None:
|
|
352
|
+
arguments["expected_entity_revision"] = expected_entity_revision
|
|
353
|
+
rid, text = self._admit(
|
|
354
|
+
"detach_component", arguments, request_id, expected_revision,
|
|
355
|
+
)
|
|
356
|
+
return self._wired("detach_component", "ENGINE-ECS")(
|
|
357
|
+
entity, component, rid, text,
|
|
358
|
+
expected_revision=expected_revision,
|
|
359
|
+
expected_entity_revision=expected_entity_revision,
|
|
360
|
+
)
|
|
361
|
+
|
|
362
|
+
def delete_entity(self, entity, request_id=None,
|
|
363
|
+
expected_revision=None,
|
|
364
|
+
expected_entity_revision=None):
|
|
365
|
+
"""Delete one entity through admission.
|
|
366
|
+
|
|
367
|
+
Args:
|
|
368
|
+
entity: Entity id to delete.
|
|
369
|
+
request_id: Client envelope id for idempotent replay.
|
|
370
|
+
expected_revision: Revision the writer read.
|
|
371
|
+
expected_entity_revision: Entity revision the writer
|
|
372
|
+
read (ENTITY-CAS).
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
Mutation mapping with entity, storage path, revision
|
|
376
|
+
transition, new head, actor, diff summary, rewind
|
|
377
|
+
handle, the entity_deleted record, cursor, and
|
|
378
|
+
request id.
|
|
379
|
+
|
|
380
|
+
Raises:
|
|
381
|
+
ProjectError: unsupported_operation until the
|
|
382
|
+
ENGINE-ECS wiring lands; unknown_entity for a
|
|
383
|
+
missing entity; backfill_readonly for a
|
|
384
|
+
backfilled id; revision_conflict for a stale
|
|
385
|
+
head.
|
|
386
|
+
|
|
387
|
+
Caution: Deleting advances the head like any mutation —
|
|
388
|
+
stale writers fail instead of merging.
|
|
389
|
+
"""
|
|
390
|
+
arguments = {"entity": entity}
|
|
391
|
+
if expected_entity_revision is not None:
|
|
392
|
+
arguments["expected_entity_revision"] = expected_entity_revision
|
|
393
|
+
rid, text = self._admit(
|
|
394
|
+
"delete_entity", arguments, request_id, expected_revision,
|
|
395
|
+
)
|
|
396
|
+
return self._wired("delete_entity", "ENGINE-ECS")(
|
|
397
|
+
entity, rid, text, expected_revision=expected_revision,
|
|
398
|
+
expected_entity_revision=expected_entity_revision,
|
|
399
|
+
)
|
|
400
|
+
|
|
401
|
+
def place_wire(self, segments, layer, endpoints, request_id=None,
|
|
402
|
+
expected_revision=None):
|
|
403
|
+
"""Place one wire through admission.
|
|
404
|
+
|
|
405
|
+
Args:
|
|
406
|
+
segments: Non-empty list of integer polylines.
|
|
407
|
+
layer: Layer name for every segment.
|
|
408
|
+
endpoints: Exactly two endpoint mappings with xy plus
|
|
409
|
+
a pin/port/junction/net id or null when dangling.
|
|
410
|
+
request_id: Client envelope id for idempotent replay.
|
|
411
|
+
expected_revision: Revision the writer read.
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
Mutation mapping with the wire receipt, revision
|
|
415
|
+
transition, actor, diff summary, rewind handle,
|
|
416
|
+
appended record, cursor, and request id.
|
|
417
|
+
|
|
418
|
+
Raises:
|
|
419
|
+
ProjectError: unsupported_operation until the
|
|
420
|
+
WIRE-PLACE wiring lands; invalid_wire for a
|
|
421
|
+
malformed wire; unknown_ref for a dangling id
|
|
422
|
+
naming no entity; revision_conflict for a stale
|
|
423
|
+
head.
|
|
424
|
+
|
|
425
|
+
Caution: Every accepted place advances the head — a
|
|
426
|
+
second writer at the old head fails instead of
|
|
427
|
+
merging.
|
|
428
|
+
"""
|
|
429
|
+
rid, text = self._admit(
|
|
430
|
+
"place_wire",
|
|
431
|
+
{"segments": segments, "layer": layer,
|
|
432
|
+
"endpoints": endpoints},
|
|
433
|
+
request_id, expected_revision,
|
|
434
|
+
)
|
|
435
|
+
return self._wired("place_wire", "WIRE-PLACE")(
|
|
436
|
+
segments, layer, endpoints, rid, text,
|
|
437
|
+
expected_revision=expected_revision,
|
|
438
|
+
)
|
|
439
|
+
|
|
440
|
+
def place_junction(self, xy, layer, request_id=None,
|
|
441
|
+
expected_revision=None):
|
|
442
|
+
"""Place one junction dot through admission.
|
|
443
|
+
|
|
444
|
+
Args:
|
|
445
|
+
xy: Integer dot position.
|
|
446
|
+
layer: Layer name for the dot.
|
|
447
|
+
request_id: Client envelope id for idempotent replay.
|
|
448
|
+
expected_revision: Revision the writer read.
|
|
449
|
+
|
|
450
|
+
Returns:
|
|
451
|
+
Mutation mapping with the junction receipt, revision
|
|
452
|
+
transition, actor, diff summary, rewind handle,
|
|
453
|
+
appended record, cursor, and request id.
|
|
454
|
+
|
|
455
|
+
Raises:
|
|
456
|
+
ProjectError: unsupported_operation until the
|
|
457
|
+
WIRE-PLACE wiring lands; invalid_junction for a
|
|
458
|
+
malformed dot; revision_conflict for a stale
|
|
459
|
+
head.
|
|
460
|
+
|
|
461
|
+
Caution: Every accepted place advances the head — a
|
|
462
|
+
second writer at the old head fails instead of
|
|
463
|
+
merging.
|
|
464
|
+
"""
|
|
465
|
+
rid, text = self._admit(
|
|
466
|
+
"place_junction", {"xy": xy, "layer": layer},
|
|
467
|
+
request_id, expected_revision,
|
|
468
|
+
)
|
|
469
|
+
return self._wired("place_junction", "WIRE-PLACE")(
|
|
470
|
+
xy, layer, rid, text, expected_revision=expected_revision
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
def connect_endpoint(self, wire_id, end, ref, request_id=None,
|
|
474
|
+
expected_revision=None):
|
|
475
|
+
"""Terminate one wire endpoint on an id through admission.
|
|
476
|
+
|
|
477
|
+
Args:
|
|
478
|
+
wire_id: Wire entity to connect.
|
|
479
|
+
end: Endpoint selector (a or b).
|
|
480
|
+
ref: Pin/port/junction/net entity id, or null to
|
|
481
|
+
leave the end dangling.
|
|
482
|
+
request_id: Client envelope id for idempotent replay.
|
|
483
|
+
expected_revision: Revision the writer read.
|
|
484
|
+
|
|
485
|
+
Returns:
|
|
486
|
+
Mutation mapping with the connect receipt, revision
|
|
487
|
+
transition, actor, diff summary, rewind handle,
|
|
488
|
+
appended record, cursor, and request id.
|
|
489
|
+
|
|
490
|
+
Raises:
|
|
491
|
+
ProjectError: unsupported_operation until the
|
|
492
|
+
WIRE-PLACE wiring lands; unknown_wire for a
|
|
493
|
+
missing wire; unknown_ref for an id naming no
|
|
494
|
+
entity; revision_conflict for a stale head.
|
|
495
|
+
|
|
496
|
+
Caution: Every accepted connect advances the head — a
|
|
497
|
+
second writer at the old head fails instead of
|
|
498
|
+
merging.
|
|
499
|
+
"""
|
|
500
|
+
rid, text = self._admit(
|
|
501
|
+
"connect_endpoint",
|
|
502
|
+
{"wire_id": wire_id, "end": end, "ref": ref},
|
|
503
|
+
request_id, expected_revision,
|
|
504
|
+
)
|
|
505
|
+
return self._wired("connect_endpoint", "WIRE-PLACE")(
|
|
506
|
+
wire_id, end, ref, rid, text,
|
|
507
|
+
expected_revision=expected_revision,
|
|
508
|
+
)
|
|
509
|
+
|
|
510
|
+
def move_wire(self, wire_id, dx, dy, request_id=None,
|
|
511
|
+
expected_revision=None):
|
|
512
|
+
"""Shift one wire by a delta through admission.
|
|
513
|
+
|
|
514
|
+
Args:
|
|
515
|
+
wire_id: Wire entity to move.
|
|
516
|
+
dx: Integer x shift.
|
|
517
|
+
dy: Integer y shift.
|
|
518
|
+
request_id: Client envelope id for idempotent replay.
|
|
519
|
+
expected_revision: Revision the writer read.
|
|
520
|
+
|
|
521
|
+
Returns:
|
|
522
|
+
Mutation mapping with the move receipt, revision
|
|
523
|
+
transition, actor, diff summary, rewind handle,
|
|
524
|
+
appended record, cursor, and request id.
|
|
525
|
+
|
|
526
|
+
Raises:
|
|
527
|
+
ProjectError: unsupported_operation until the
|
|
528
|
+
WIRE-PLACE wiring lands; unknown_wire for a
|
|
529
|
+
missing wire; revision_conflict for a stale
|
|
530
|
+
head.
|
|
531
|
+
|
|
532
|
+
Caution: Every accepted move advances the head — a
|
|
533
|
+
second writer at the old head fails instead of
|
|
534
|
+
merging.
|
|
535
|
+
"""
|
|
536
|
+
rid, text = self._admit(
|
|
537
|
+
"move_wire", {"wire_id": wire_id, "dx": dx, "dy": dy},
|
|
538
|
+
request_id, expected_revision,
|
|
539
|
+
)
|
|
540
|
+
return self._wired("move_wire", "WIRE-PLACE")(
|
|
541
|
+
wire_id, dx, dy, rid, text,
|
|
542
|
+
expected_revision=expected_revision,
|
|
543
|
+
)
|
|
544
|
+
|
|
545
|
+
def split_wire(self, wire_id, at, request_id=None,
|
|
546
|
+
expected_revision=None):
|
|
547
|
+
"""Split one wire at a point through admission.
|
|
548
|
+
|
|
549
|
+
Args:
|
|
550
|
+
wire_id: Wire entity to split.
|
|
551
|
+
at: Integer point on the wire marking the split.
|
|
552
|
+
request_id: Client envelope id for idempotent replay.
|
|
553
|
+
expected_revision: Revision the writer read.
|
|
554
|
+
|
|
555
|
+
Returns:
|
|
556
|
+
Mutation mapping with the split receipt, revision
|
|
557
|
+
transition, actor, diff summary, rewind handle,
|
|
558
|
+
appended record, cursor, and request id.
|
|
559
|
+
|
|
560
|
+
Raises:
|
|
561
|
+
ProjectError: unsupported_operation until the
|
|
562
|
+
WIRE-PLACE wiring lands; unknown_wire for a
|
|
563
|
+
missing wire; invalid_split for a point off the
|
|
564
|
+
wire; revision_conflict for a stale head.
|
|
565
|
+
|
|
566
|
+
Caution: Every accepted split advances the head — a
|
|
567
|
+
second writer at the old head fails instead of
|
|
568
|
+
merging.
|
|
569
|
+
"""
|
|
570
|
+
rid, text = self._admit(
|
|
571
|
+
"split_wire", {"wire_id": wire_id, "at": at},
|
|
572
|
+
request_id, expected_revision,
|
|
573
|
+
)
|
|
574
|
+
return self._wired("split_wire", "WIRE-PLACE")(
|
|
575
|
+
wire_id, at, rid, text, expected_revision=expected_revision
|
|
576
|
+
)
|
|
577
|
+
|
|
578
|
+
def delete_wire(self, wire_id, request_id=None,
|
|
579
|
+
expected_revision=None):
|
|
580
|
+
"""Delete one wire through admission.
|
|
581
|
+
|
|
582
|
+
Args:
|
|
583
|
+
wire_id: Wire entity to delete.
|
|
584
|
+
request_id: Client envelope id for idempotent replay.
|
|
585
|
+
expected_revision: Revision the writer read.
|
|
586
|
+
|
|
587
|
+
Returns:
|
|
588
|
+
Mutation mapping with the delete receipt, revision
|
|
589
|
+
transition, actor, diff summary, rewind handle,
|
|
590
|
+
appended record, cursor, and request id.
|
|
591
|
+
|
|
592
|
+
Raises:
|
|
593
|
+
ProjectError: unsupported_operation until the
|
|
594
|
+
WIRE-PLACE wiring lands; unknown_wire for a
|
|
595
|
+
missing wire; revision_conflict for a stale
|
|
596
|
+
head.
|
|
597
|
+
|
|
598
|
+
Caution: Deleting advances the head like any mutation —
|
|
599
|
+
stale writers fail instead of merging.
|
|
600
|
+
"""
|
|
601
|
+
rid, text = self._admit(
|
|
602
|
+
"delete_wire", {"wire_id": wire_id}, request_id,
|
|
603
|
+
expected_revision,
|
|
604
|
+
)
|
|
605
|
+
return self._wired("delete_wire", "WIRE-PLACE")(
|
|
606
|
+
wire_id, rid, text, expected_revision=expected_revision
|
|
607
|
+
)
|
|
608
|
+
|
|
609
|
+
def delete_junction(self, junction_id, request_id=None,
|
|
610
|
+
expected_revision=None):
|
|
611
|
+
"""Delete one junction through admission.
|
|
612
|
+
|
|
613
|
+
Args:
|
|
614
|
+
junction_id: Junction entity to delete.
|
|
615
|
+
request_id: Client envelope id for idempotent replay.
|
|
616
|
+
expected_revision: Revision the writer read.
|
|
617
|
+
|
|
618
|
+
Returns:
|
|
619
|
+
Mutation mapping with the delete receipt, revision
|
|
620
|
+
transition, actor, diff summary, rewind handle,
|
|
621
|
+
appended record, cursor, and request id.
|
|
622
|
+
|
|
623
|
+
Raises:
|
|
624
|
+
ProjectError: unsupported_operation until the
|
|
625
|
+
WIRE-PLACE wiring lands; unknown_junction for a
|
|
626
|
+
missing junction; junction_in_use for a dot still
|
|
627
|
+
referenced; revision_conflict for a stale head.
|
|
628
|
+
|
|
629
|
+
Caution: Deleting advances the head like any mutation —
|
|
630
|
+
stale writers fail instead of merging.
|
|
631
|
+
"""
|
|
632
|
+
rid, text = self._admit(
|
|
633
|
+
"delete_junction", {"junction_id": junction_id},
|
|
634
|
+
request_id, expected_revision,
|
|
635
|
+
)
|
|
636
|
+
return self._wired("delete_junction", "WIRE-PLACE")(
|
|
637
|
+
junction_id, rid, text,
|
|
638
|
+
expected_revision=expected_revision,
|
|
639
|
+
)
|
|
640
|
+
|
|
641
|
+
def materialize_nets(self, pins, request_id=None,
|
|
642
|
+
expected_revision=None, labels=None,
|
|
643
|
+
ports=None, cell="top", named_refs=None):
|
|
644
|
+
"""Materialize net entities through admission.
|
|
645
|
+
|
|
646
|
+
Args:
|
|
647
|
+
pins: Caller pin records mapping entities to their
|
|
648
|
+
schematic triples.
|
|
649
|
+
request_id: Client envelope id for idempotent replay.
|
|
650
|
+
expected_revision: Revision the writer read.
|
|
651
|
+
labels: Optional label records for extraction.
|
|
652
|
+
ports: Optional port records for extraction.
|
|
653
|
+
cell: Cell name extraction runs under.
|
|
654
|
+
named_refs: Optional net-ref taps by name.
|
|
655
|
+
|
|
656
|
+
Returns:
|
|
657
|
+
Mutation mapping with the materialize receipt,
|
|
658
|
+
revision transition, actor, diff summary, rewind
|
|
659
|
+
handle, appended record, cursor, and request id.
|
|
660
|
+
|
|
661
|
+
Raises:
|
|
662
|
+
ProjectError: unsupported_operation until the
|
|
663
|
+
WIRE-PLACE wiring lands; invalid_pin and sibling
|
|
664
|
+
contract codes for malformed inputs;
|
|
665
|
+
revision_conflict for a stale head.
|
|
666
|
+
|
|
667
|
+
Caution: Every accepted materialize advances the head —
|
|
668
|
+
a second writer at the old head fails instead of
|
|
669
|
+
merging.
|
|
670
|
+
"""
|
|
671
|
+
arguments = {"pins": pins, "cell": cell}
|
|
672
|
+
if labels is not None:
|
|
673
|
+
arguments["labels"] = labels
|
|
674
|
+
if ports is not None:
|
|
675
|
+
arguments["ports"] = ports
|
|
676
|
+
if named_refs is not None:
|
|
677
|
+
arguments["named_refs"] = named_refs
|
|
678
|
+
rid, text = self._admit(
|
|
679
|
+
"materialize_nets", arguments, request_id,
|
|
680
|
+
expected_revision,
|
|
681
|
+
)
|
|
682
|
+
return self._wired("materialize_nets", "WIRE-PLACE")(
|
|
683
|
+
pins, rid, text, labels=labels, ports=ports, cell=cell,
|
|
684
|
+
named_refs=named_refs, expected_revision=expected_revision,
|
|
685
|
+
)
|
|
686
|
+
|
|
687
|
+
def create_project(self, new_project_id, request_id=None):
|
|
688
|
+
"""Create one managed project at its first head.
|
|
689
|
+
|
|
690
|
+
New ledgers start clean, so creation binds no revision —
|
|
691
|
+
the envelope id alone carries idempotency.
|
|
692
|
+
|
|
693
|
+
Args:
|
|
694
|
+
new_project_id: Slug for the project to create.
|
|
695
|
+
request_id: Client envelope id; resubmitting the
|
|
696
|
+
identical call returns the identical response.
|
|
697
|
+
|
|
698
|
+
Returns:
|
|
699
|
+
Creation mapping with the new project id, first head,
|
|
700
|
+
actor, diff summary, revision transition, rewind
|
|
701
|
+
handle, empty records, and request id.
|
|
702
|
+
|
|
703
|
+
Raises:
|
|
704
|
+
ProjectError: invalid_command without an engine root;
|
|
705
|
+
invalid_project for a non-slug id;
|
|
706
|
+
project_exists for a duplicate; request_conflict
|
|
707
|
+
for a reused id with new arguments.
|
|
708
|
+
"""
|
|
709
|
+
rid, text = self._admit(
|
|
710
|
+
"create_project", {"new_project_id": new_project_id},
|
|
711
|
+
request_id, None,
|
|
712
|
+
)
|
|
713
|
+
return self._project.create_project(new_project_id, rid, text)
|
|
714
|
+
|
|
715
|
+
def rewind(self, target_revision, request_id=None,
|
|
716
|
+
expected_revision=None):
|
|
717
|
+
"""Restore a prior head under a new head through admission.
|
|
718
|
+
|
|
719
|
+
Args:
|
|
720
|
+
target_revision: Stored head to restore.
|
|
721
|
+
request_id: Client envelope id for idempotent replay.
|
|
722
|
+
expected_revision: Revision the writer read.
|
|
723
|
+
|
|
724
|
+
Returns:
|
|
725
|
+
Mutation mapping with revision transition, target
|
|
726
|
+
revision, new head, actor, diff summary,
|
|
727
|
+
external-file report, rewind handle, the appended
|
|
728
|
+
record, cursor, and request id.
|
|
729
|
+
|
|
730
|
+
Raises:
|
|
731
|
+
ProjectError: request_conflict for a reused id with
|
|
732
|
+
new arguments; invalid_command for a missing
|
|
733
|
+
target or a target equal to the live head;
|
|
734
|
+
unknown_revision for a head with no stored
|
|
735
|
+
bytes; revision_conflict for a stale head.
|
|
736
|
+
|
|
737
|
+
Caution: Rewinding advances — the new head is not the
|
|
738
|
+
target id, and stale writers fail instead of merging.
|
|
739
|
+
"""
|
|
740
|
+
rid, text = self._admit(
|
|
741
|
+
"rewind", {"target_revision": target_revision},
|
|
742
|
+
request_id, expected_revision,
|
|
743
|
+
)
|
|
744
|
+
return self._project.rewind(
|
|
745
|
+
target_revision, rid, text,
|
|
746
|
+
expected_revision=expected_revision,
|
|
747
|
+
)
|
|
748
|
+
|
|
749
|
+
def write_settings(self, kind, settings, request_id=None,
|
|
750
|
+
expected_revision=None):
|
|
751
|
+
"""Write one settings kind through admission.
|
|
752
|
+
|
|
753
|
+
Args:
|
|
754
|
+
kind: Settings kind to replace wholesale.
|
|
755
|
+
settings: Complete settings mapping at the head
|
|
756
|
+
version.
|
|
757
|
+
request_id: Client envelope id for idempotent replay.
|
|
758
|
+
expected_revision: Revision the writer read.
|
|
759
|
+
|
|
760
|
+
Returns:
|
|
761
|
+
Mutation mapping with path, revision transition, new
|
|
762
|
+
head, actor, diff summary, rewind handle, the
|
|
763
|
+
appended record, cursor, request id, written
|
|
764
|
+
flag, and settings version.
|
|
765
|
+
|
|
766
|
+
Raises:
|
|
767
|
+
ProjectError: request_conflict for a reused id with
|
|
768
|
+
new arguments; invalid_command for an unknown
|
|
769
|
+
kind or settings breaking the kind schema;
|
|
770
|
+
revision_conflict for a stale head;
|
|
771
|
+
future_format when the stored file is newer
|
|
772
|
+
than the head.
|
|
773
|
+
|
|
774
|
+
Caution: Every accepted write advances the head — a
|
|
775
|
+
second writer at the old head fails instead of
|
|
776
|
+
merging.
|
|
777
|
+
"""
|
|
778
|
+
rid, text = self._admit(
|
|
779
|
+
"write_settings", {"kind": kind, "settings": settings},
|
|
780
|
+
request_id, expected_revision,
|
|
781
|
+
)
|
|
782
|
+
return self._project.write_settings(
|
|
783
|
+
kind, settings, rid, text,
|
|
784
|
+
expected_revision=expected_revision,
|
|
785
|
+
)
|