@substrat-run/contracts 0.118.0 → 0.119.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/dist/connection-health.d.ts +132 -0
- package/dist/connection-health.d.ts.map +1 -0
- package/dist/connection-health.js +132 -0
- package/dist/connection-health.js.map +1 -0
- package/dist/control-plane.d.ts +20 -1
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +26 -2
- package/dist/control-plane.js.map +1 -1
- package/dist/denial.d.ts +12 -0
- package/dist/denial.d.ts.map +1 -1
- package/dist/deploy.d.ts +68 -0
- package/dist/deploy.d.ts.map +1 -1
- package/dist/deploy.js +91 -1
- package/dist/deploy.js.map +1 -1
- package/dist/events.d.ts +42 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/events.js +26 -2
- package/dist/events.js.map +1 -1
- package/dist/ids.d.ts +1 -0
- package/dist/ids.d.ts.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +58 -0
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +109 -3
- package/dist/manifest.js.map +1 -1
- package/dist/operations.d.ts +67 -0
- package/dist/operations.d.ts.map +1 -1
- package/dist/operations.js +111 -0
- package/dist/operations.js.map +1 -1
- package/dist/peer-transport.d.ts +81 -0
- package/dist/peer-transport.d.ts.map +1 -0
- package/dist/peer-transport.js +87 -0
- package/dist/peer-transport.js.map +1 -0
- package/dist/peer.d.ts +183 -0
- package/dist/peer.d.ts.map +1 -0
- package/dist/peer.js +155 -0
- package/dist/peer.js.map +1 -0
- package/dist/permission.d.ts +42 -1
- package/dist/permission.d.ts.map +1 -1
- package/dist/permission.js +36 -2
- package/dist/permission.js.map +1 -1
- package/dist/platform-request.d.ts +50 -0
- package/dist/platform-request.d.ts.map +1 -1
- package/dist/platform-request.js +53 -1
- package/dist/platform-request.js.map +1 -1
- package/dist/preview-client.d.ts +154 -0
- package/dist/preview-client.d.ts.map +1 -0
- package/dist/preview-client.js +157 -0
- package/dist/preview-client.js.map +1 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -0
- package/dist/registry.js.map +1 -1
- package/dist/routing.d.ts +1 -0
- package/dist/routing.d.ts.map +1 -1
- package/dist/routing.js +9 -0
- package/dist/routing.js.map +1 -1
- package/dist/vertical-events.d.ts +265 -0
- package/dist/vertical-events.d.ts.map +1 -0
- package/dist/vertical-events.js +167 -0
- package/dist/vertical-events.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { eventId, instant, permissionKey, scopeId, verticalSlug } from './ids.js';
|
|
3
|
+
import { entityRef, eventType } from './events.js';
|
|
4
|
+
// Cross-vertical event delivery (#1705): the three messages the platform carries between a
|
|
5
|
+
// producer vertical's scope and a consumer vertical's scope in the same tenant.
|
|
6
|
+
//
|
|
7
|
+
// The shape of the whole thing, so the schemas below read in context. An export is a
|
|
8
|
+
// declaration over the producer's OWN outbox, which is retained, so nothing new is written
|
|
9
|
+
// when an exported event commits. The platform sweep asks the consumer where it got to
|
|
10
|
+
// (`importState`), reads the producer's outbox after that watermark (`exportRead`), and
|
|
11
|
+
// hands the batch to the consumer (`importBatch`). The consumer runs its handlers and moves
|
|
12
|
+
// its watermark in the same store as their writes. Because the consumer holds the cursor,
|
|
13
|
+
// a restore of the consumer rewinds the cursor and the data together, and a consumer
|
|
14
|
+
// installed after the producer starts from the beginning of the exported history.
|
|
15
|
+
/**
|
|
16
|
+
* One exported event as it crosses (#1705): the domain fact, and not the producer's
|
|
17
|
+
* record of who was allowed to cause it.
|
|
18
|
+
*
|
|
19
|
+
* Deliberately NOT the envelope (`domainEvent`). `actor`, `authorization` and
|
|
20
|
+
* `impersonation` describe authority inside the producer's scope: a principal id that
|
|
21
|
+
* means nothing to another vertical and identifies a person to anyone who can join it
|
|
22
|
+
* back, the K-34 chain, and a staff session. None of that is the consumer's to hold. So is
|
|
23
|
+
* `piiClass`: only `none` crosses, so the field would carry one value. `subjectId` crosses
|
|
24
|
+
* neither, because a `none` event has none.
|
|
25
|
+
*
|
|
26
|
+
* `hops` is how many vertical boundaries this event's cause chain has crossed, counting
|
|
27
|
+
* this one. It is what breaks a P ↔ C loop. The in-scope cascade cap only defers a round
|
|
28
|
+
* to the next call, so it would let two verticals feed each other forever at sweep pace.
|
|
29
|
+
*/
|
|
30
|
+
export const exportedEvent = z.object({
|
|
31
|
+
id: eventId,
|
|
32
|
+
type: eventType,
|
|
33
|
+
schemaVersion: z.number().int().positive(),
|
|
34
|
+
occurredAt: instant,
|
|
35
|
+
entity: entityRef,
|
|
36
|
+
payload: z.unknown(),
|
|
37
|
+
hops: z.number().int().positive(),
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* Why an event of a type the consumer asked for was not released to it (#1705).
|
|
41
|
+
*
|
|
42
|
+
* Each is PERMANENT for that event, which is what licenses stepping the watermark
|
|
43
|
+
* past it: the classification, the version and the cause chain are all fixed once
|
|
44
|
+
* the row is written, so asking again cannot change the answer. Authority is
|
|
45
|
+
* deliberately NOT a reason here. It can change, so a missing key pauses the whole
|
|
46
|
+
* edge (`paused`) instead of dropping what arrived while it was missing.
|
|
47
|
+
*
|
|
48
|
+
* - `pii`: the row is classified other than `none`. Only textless events cross.
|
|
49
|
+
* - `version`: the row's schemaVersion is not the one the consumer declares (K-39:
|
|
50
|
+
* a strict parse on the other side would reject it, so it is never handed over).
|
|
51
|
+
* - `cascade`: the cause chain has already crossed the maximum number of vertical
|
|
52
|
+
* boundaries.
|
|
53
|
+
* - `undecodable`: the stored row does not decode (#1636). The decode is pure, of text
|
|
54
|
+
* already written, so a retry cannot succeed. The in-scope consumers dead-letter the same
|
|
55
|
+
* row for the same reason.
|
|
56
|
+
*/
|
|
57
|
+
export const withheldReason = z.enum(['pii', 'version', 'cascade', 'undecodable']);
|
|
58
|
+
/**
|
|
59
|
+
* A withheld row, named but not carried: no payload crosses. The fields are the stored
|
|
60
|
+
* columns, read leniently, because an `undecodable` row is the one whose columns may be
|
|
61
|
+
* exactly what failed. The consumer journals this as a dead letter, so its operator sees
|
|
62
|
+
* that something was sent and not delivered.
|
|
63
|
+
*/
|
|
64
|
+
export const withheldEvent = z.object({
|
|
65
|
+
id: eventId,
|
|
66
|
+
type: z.string().min(1),
|
|
67
|
+
schemaVersion: z.number().int(),
|
|
68
|
+
occurredAt: z.string().min(1),
|
|
69
|
+
entity: z.object({ entityType: z.string().min(1), entityId: z.string().min(1) }),
|
|
70
|
+
reason: withheldReason,
|
|
71
|
+
});
|
|
72
|
+
/** One (type, version) a consumer declares it receives from a given producer. */
|
|
73
|
+
export const wantedEvent = z.object({
|
|
74
|
+
type: eventType,
|
|
75
|
+
schemaVersion: z.number().int().positive(),
|
|
76
|
+
});
|
|
77
|
+
/**
|
|
78
|
+
* The producer-side read (#1705): what the platform asks a producer scope for.
|
|
79
|
+
*
|
|
80
|
+
* `consumer` is the receiving vertical's slug, asserted by the platform from its directory
|
|
81
|
+
* and never taken from either vertical. `wants` is what the consumer declares, and it is a
|
|
82
|
+
* request, not an authority: the producer answers from its own running `exports`, so a type
|
|
83
|
+
* it does not export is never released however it is asked for.
|
|
84
|
+
*/
|
|
85
|
+
export const exportReadInput = z.object({
|
|
86
|
+
consumer: verticalSlug,
|
|
87
|
+
/** The consumer's watermark: the last event id it has taken from this producer, or null. */
|
|
88
|
+
after: eventId.nullable(),
|
|
89
|
+
wants: z.array(wantedEvent).min(1),
|
|
90
|
+
limit: z.number().int().min(1).max(1000),
|
|
91
|
+
});
|
|
92
|
+
/**
|
|
93
|
+
* The producer's answer (#1705).
|
|
94
|
+
*
|
|
95
|
+
* `next` is the watermark the consumer should hold once it has taken this batch: the id of
|
|
96
|
+
* the last row the read WALKED, released or withheld. A withheld row is stepped over
|
|
97
|
+
* because its reason is permanent. A paused edge answers with `next === after` and no
|
|
98
|
+
* events: the read walked nothing, so the producer's outbox keeps the backlog.
|
|
99
|
+
*
|
|
100
|
+
* `paused` lists the keys the consumer's principal does not hold here. `unexported`
|
|
101
|
+
* lists what the consumer wants and this producer does not export at all. That is
|
|
102
|
+
* reported rather than paused, because a consumer may declare an import its producer has
|
|
103
|
+
* not shipped yet.
|
|
104
|
+
*/
|
|
105
|
+
export const exportedBatch = z.object({
|
|
106
|
+
events: z.array(exportedEvent),
|
|
107
|
+
withheld: z.array(withheldEvent),
|
|
108
|
+
unexported: z.array(wantedEvent),
|
|
109
|
+
paused: z.object({ missing: z.array(permissionKey).min(1) }).nullable(),
|
|
110
|
+
next: eventId.nullable(),
|
|
111
|
+
/** The read stopped at `limit`, so more rows may be waiting. */
|
|
112
|
+
more: z.boolean(),
|
|
113
|
+
});
|
|
114
|
+
/** One producer a consumer scope has taken events from, and how far (#1705). */
|
|
115
|
+
export const importCursor = z.object({
|
|
116
|
+
source: scopeId,
|
|
117
|
+
vertical: verticalSlug,
|
|
118
|
+
cursor: eventId.nullable(),
|
|
119
|
+
updatedAt: instant.nullable(),
|
|
120
|
+
});
|
|
121
|
+
/**
|
|
122
|
+
* What a consumer scope says about itself before a pass (#1705): what its RUNNING code
|
|
123
|
+
* imports, and its watermark per producer. Both come from the consumer, not the registry,
|
|
124
|
+
* because the version serving the scope is the one whose handlers will run.
|
|
125
|
+
*/
|
|
126
|
+
export const importState = z.object({
|
|
127
|
+
consumes: z.array(z.object({ from: verticalSlug, type: eventType, schemaVersion: z.number().int().positive() })),
|
|
128
|
+
cursors: z.array(importCursor),
|
|
129
|
+
});
|
|
130
|
+
/**
|
|
131
|
+
* The batch handed to the consumer (#1705).
|
|
132
|
+
*
|
|
133
|
+
* `after` is a compare-and-set: the consumer applies the batch only if its watermark for
|
|
134
|
+
* this source is still `after`. Two overlapping passes (a sweep that outruns its interval)
|
|
135
|
+
* would otherwise each apply what they read, and the one that read less would move the
|
|
136
|
+
* watermark BACKWARDS. The redelivery that caused would be absorbed by the delivery
|
|
137
|
+
* journal, but it is still work nobody asked for.
|
|
138
|
+
*/
|
|
139
|
+
export const importBatch = z.object({
|
|
140
|
+
source: z.object({ vertical: verticalSlug, scopeId }),
|
|
141
|
+
after: eventId.nullable(),
|
|
142
|
+
next: eventId,
|
|
143
|
+
events: z.array(exportedEvent),
|
|
144
|
+
withheld: z.array(withheldEvent),
|
|
145
|
+
});
|
|
146
|
+
/**
|
|
147
|
+
* What applying one batch did (#1705).
|
|
148
|
+
*
|
|
149
|
+
* `stale`: the compare-and-set refused the batch, and nothing ran. `paused`: this scope
|
|
150
|
+
* refused the producer at its door. The producer is not a declared peer here, or its kill
|
|
151
|
+
* switch is off, so nothing ran, the watermark did not move, and the producer's outbox keeps
|
|
152
|
+
* the backlog until the peer is admitted again. It is the consumer side's twin of
|
|
153
|
+
* `ExportedBatch.paused`.
|
|
154
|
+
*/
|
|
155
|
+
export const importResult = z.object({
|
|
156
|
+
delivered: z.number().int().nonnegative(),
|
|
157
|
+
deadLettered: z.number().int().nonnegative(),
|
|
158
|
+
/** Events already journaled here, from an earlier pass, and skipped. */
|
|
159
|
+
duplicates: z.number().int().nonnegative(),
|
|
160
|
+
withheld: z.number().int().nonnegative(),
|
|
161
|
+
cursor: eventId.nullable(),
|
|
162
|
+
stale: z.boolean(),
|
|
163
|
+
paused: z.object({ reason: z.string().min(1) }).nullable(),
|
|
164
|
+
});
|
|
165
|
+
/** How many vertical boundaries a cause chain may cross before its next export is withheld. */
|
|
166
|
+
export const EXPORT_HOP_CAP = 8;
|
|
167
|
+
//# sourceMappingURL=vertical-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vertical-events.js","sourceRoot":"","sources":["../src/vertical-events.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@substrat-run/contracts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.119.0",
|
|
4
4
|
"description": "Substrat kernel contract schemas — Zod is the source of truth (master plan D-22); OAS/JSON Schema are emitted artifacts",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|