@volter/world-core 3.0.38 → 3.0.39
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/app-route.cjs +26 -25
- package/app-route.d.cts +1 -0
- package/dist/app-route.cjs +26 -25
- package/dist/app-route.d.cts +1 -0
- package/dist/generated/pack-facts.json +409 -352
- package/dist/inject.cjs +474 -95
- package/dist/network-policy.cjs +108 -13
- package/dist/network-policy.d.cts +8 -3
- package/dist/src/actions.js +2 -1
- package/dist/src/anthropic-wire.d.ts +2 -0
- package/dist/src/anthropic-wire.js +5 -0
- package/dist/src/attestation.d.ts +6 -0
- package/dist/src/attestation.js +27 -0
- package/dist/src/bytes.d.ts +3 -0
- package/dist/src/bytes.js +17 -0
- package/dist/src/changeset.js +2 -1
- package/dist/src/clickhouse/sql.js +73 -14
- package/dist/src/derived-core.d.ts +210 -32
- package/dist/src/derived-core.js +510 -244
- package/dist/src/derived-real.d.ts +1 -1
- package/dist/src/derived-real.js +704 -93
- package/dist/src/derived.d.ts +18 -2
- package/dist/src/derived.js +21 -2
- package/dist/src/events.d.ts +28 -45
- package/dist/src/events.js +40 -58
- package/dist/src/exact-json.d.ts +10 -0
- package/dist/src/exact-json.js +98 -0
- package/dist/src/executor.d.ts +17 -0
- package/dist/src/executor.js +91 -30
- package/dist/src/file-response.js +1 -1
- package/dist/src/form.d.ts +8 -0
- package/dist/src/form.js +76 -0
- package/dist/src/git/format.d.ts +16 -0
- package/dist/src/git/format.js +110 -0
- package/dist/src/git/index.d.ts +1 -0
- package/dist/src/git/index.js +1 -0
- package/dist/src/git/lfs.d.ts +1 -1
- package/dist/src/git/lfs.js +4 -3
- package/dist/src/graphql-wire.d.ts +6 -0
- package/dist/src/graphql-wire.js +6 -3
- package/dist/src/grpc-wire.js +2 -1
- package/dist/src/head.d.ts +1 -0
- package/dist/src/head.js +15 -4
- package/dist/src/held-reads.d.ts +6 -0
- package/dist/src/held-reads.js +60 -0
- package/dist/src/history.js +5 -4
- package/dist/src/host-port.d.ts +5 -0
- package/dist/src/host-port.js +14 -0
- package/dist/src/index.d.ts +11 -3
- package/dist/src/index.js +9 -4
- package/dist/src/log.js +12 -7
- package/dist/src/machines.d.ts +81 -5
- package/dist/src/machines.js +125 -9
- package/dist/src/managed-database.d.ts +15 -11
- package/dist/src/managed-database.js +38 -37
- package/dist/src/multipart.d.ts +21 -3
- package/dist/src/multipart.js +112 -38
- package/dist/src/observe.d.ts +3 -0
- package/dist/src/observe.js +6 -2
- package/dist/src/openai-wire.d.ts +16 -0
- package/dist/src/openai-wire.js +43 -12
- package/dist/src/pack-fetch.d.ts +4 -6
- package/dist/src/pack-fetch.js +189 -57
- package/dist/src/packRegistry.d.ts +7 -1
- package/dist/src/packRegistry.js +20 -3
- package/dist/src/private-transport.d.ts +1 -0
- package/dist/src/private-transport.js +11 -0
- package/dist/src/protobuf.js +10 -4
- package/dist/src/rateBudget.d.ts +8 -1
- package/dist/src/rateBudget.js +1 -0
- package/dist/src/redis/engine.d.ts +14 -5
- package/dist/src/redis/engine.js +271 -72
- package/dist/src/redis/frames.d.ts +17 -0
- package/dist/src/redis/frames.js +123 -0
- package/dist/src/redis/index.d.ts +6 -0
- package/dist/src/redis/index.js +6 -0
- package/dist/src/redis/json.d.ts +2 -0
- package/dist/src/redis/json.js +14 -0
- package/dist/src/redis/lua-libs.d.ts +4 -0
- package/dist/src/redis/lua-libs.js +173 -0
- package/dist/src/redis/lua.d.ts +1 -0
- package/dist/src/redis/lua.js +36 -0
- package/dist/src/redis/member-storage.d.ts +5 -0
- package/dist/src/redis/member-storage.js +75 -0
- package/dist/src/redis/resp2.d.ts +4 -0
- package/dist/src/redis/resp2.js +29 -0
- package/dist/src/redis/stream.d.ts +14 -0
- package/dist/src/redis/stream.js +335 -0
- package/dist/src/remote-execute.d.ts +2 -2
- package/dist/src/request-body.d.ts +11 -0
- package/dist/src/request-body.js +11 -0
- package/dist/src/runtime.d.ts +6 -5
- package/dist/src/runtime.js +5 -5
- package/dist/src/s3/wire.d.ts +4 -4
- package/dist/src/s3/wire.js +5 -3
- package/dist/src/scenario.d.ts +22 -0
- package/dist/src/scenario.js +35 -31
- package/dist/src/serve-http.d.ts +2 -1
- package/dist/src/serve-http.js +10 -1
- package/dist/src/serve.js +7 -4
- package/dist/src/signing.d.ts +23 -5
- package/dist/src/signing.js +74 -11
- package/dist/src/sigv4.d.ts +3 -1
- package/dist/src/sigv4.js +4 -2
- package/dist/src/smtp.js +2 -1
- package/dist/src/sockets.js +8 -3
- package/dist/src/state-system.d.ts +3 -0
- package/dist/src/storage.js +5 -2
- package/dist/src/twin-fetch.d.ts +3 -1
- package/dist/src/twin-fetch.js +3 -2
- package/dist/src/vendor-call.d.ts +10 -3
- package/dist/src/vendor-call.js +58 -14
- package/dist/test-fixtures/attestation.SOURCE.md +1 -0
- package/dist/test-fixtures/attestation.json +50 -0
- package/generated/pack-facts.json +409 -352
- package/inject.cjs +474 -95
- package/network-policy.cjs +108 -13
- package/network-policy.d.cts +8 -3
- package/package.json +11 -4
- package/src/actions.ts +2 -1
- package/src/anthropic-wire.ts +6 -0
- package/src/attestation.ts +23 -0
- package/src/bytes.ts +21 -0
- package/src/changeset.ts +2 -1
- package/src/clickhouse/sql.ts +50 -16
- package/src/derived-core.ts +573 -249
- package/src/derived-real.ts +552 -42
- package/src/derived.ts +23 -4
- package/src/events.ts +54 -85
- package/src/exact-json.ts +71 -0
- package/src/executor.ts +86 -27
- package/src/file-response.ts +1 -1
- package/src/form.ts +66 -0
- package/src/git/format.ts +89 -0
- package/src/git/index.ts +1 -0
- package/src/git/lfs.ts +5 -4
- package/src/graphql-wire.ts +8 -3
- package/src/grpc-wire.ts +2 -1
- package/src/head.ts +15 -5
- package/src/held-reads.ts +54 -0
- package/src/history.ts +5 -4
- package/src/host-port.ts +9 -0
- package/src/index.ts +10 -4
- package/src/log.ts +11 -7
- package/src/machines.ts +135 -13
- package/src/managed-database.ts +48 -40
- package/src/multipart.ts +110 -35
- package/src/observe.ts +6 -3
- package/src/openai-wire.ts +45 -14
- package/src/pack-fetch.ts +173 -50
- package/src/packRegistry.ts +27 -4
- package/src/private-transport.ts +8 -0
- package/src/protobuf.ts +8 -4
- package/src/rateBudget.ts +6 -1
- package/src/redis/engine.ts +168 -63
- package/src/redis/frames.ts +53 -0
- package/src/redis/index.ts +6 -0
- package/src/redis/json.ts +13 -0
- package/src/redis/lua-libs.ts +62 -0
- package/src/redis/lua.ts +20 -0
- package/src/redis/member-storage.ts +58 -0
- package/src/redis/resp2.ts +25 -0
- package/src/redis/stream.ts +102 -0
- package/src/remote-execute.ts +2 -2
- package/src/request-body.ts +12 -0
- package/src/runtime.ts +6 -5
- package/src/s3/wire.ts +8 -5
- package/src/scenario.ts +34 -13
- package/src/serve-http.ts +11 -2
- package/src/serve.ts +4 -3
- package/src/signing.ts +71 -17
- package/src/sigv4.ts +5 -3
- package/src/smtp.ts +3 -2
- package/src/sockets.ts +8 -3
- package/src/state-system.ts +3 -0
- package/src/storage.ts +5 -2
- package/src/twin-fetch.ts +4 -3
- package/src/vendor-call.ts +59 -12
- package/test-fixtures/attestation.json +50 -0
|
@@ -9,8 +9,10 @@ import { type HandlerCrypto } from './signing.js';
|
|
|
9
9
|
import { type ManagedDatabase } from './managed-database.js';
|
|
10
10
|
import { type RedisDialect, type RunItem } from './redis/engine.js';
|
|
11
11
|
import { type Mail, type SmtpRoute } from './smtp.js';
|
|
12
|
+
export { ownField, parseBracketForm } from './form.js';
|
|
12
13
|
import { type MultipartPart } from './multipart.js';
|
|
13
14
|
import type { CorsDecl } from './cors.js';
|
|
15
|
+
import { type TwinAction } from './actions.js';
|
|
14
16
|
import type { DerivedCall, DerivedCoreOutcome, DerivedHandler, DerivedOperation } from './derived.js';
|
|
15
17
|
import type { PackDescriptor } from './packRegistry.js';
|
|
16
18
|
import type { ScenarioDecision, ScenarioHandler } from './scenario.js';
|
|
@@ -39,7 +41,8 @@ export type Transition = {
|
|
|
39
41
|
operation?: string;
|
|
40
42
|
actor?: Actor;
|
|
41
43
|
from: string[] | '*';
|
|
42
|
-
/** the value it moves to; absent, the value stays (a guard that moves nothing)
|
|
44
|
+
/** the value it moves to; absent, the value stays (a guard that moves nothing), and absent with a `refusal`, the
|
|
45
|
+
* operation is refused in the `from` states (a move another transition allows from there is taken first) */
|
|
43
46
|
to?: string;
|
|
44
47
|
effects?: Record<string, FieldRule>;
|
|
45
48
|
/** placeholders `{from}`, `{to}`, `{field}`, `{id}` */
|
|
@@ -90,8 +93,8 @@ export type ResourceDecl = {
|
|
|
90
93
|
setting?: {
|
|
91
94
|
defaults: Record<string, unknown>;
|
|
92
95
|
};
|
|
93
|
-
/** this resource's id template, when it is not the manifest's (`ids.template`): `{uuid}`, `{letters:20}` (twenty
|
|
94
|
-
* lowercase letters, a Supabase project ref), `{snowflake:<epoch ms>}` (Discord's ids), or a `{prefix}`/`{n}`
|
|
96
|
+
/** this resource's id template, when it is not the manifest's (`ids.template`): `{uuid}`, `{ksuid}` (Clerk's), `{letters:20}` (twenty
|
|
97
|
+
* lowercase letters, a Supabase project ref), `{digits:16}` (fixed-width decimal), `{snowflake:<epoch ms>}` (Discord's ids), or a `{prefix}`/`{n}`
|
|
95
98
|
* template */
|
|
96
99
|
ids?: string;
|
|
97
100
|
/** fields the server assigns on create */
|
|
@@ -101,6 +104,24 @@ export type ResourceDecl = {
|
|
|
101
104
|
notState?: string[];
|
|
102
105
|
/** id-holding fields a caller may ask to receive embedded, and the resource each holds */
|
|
103
106
|
embeds?: Record<string, string>;
|
|
107
|
+
/** `embeds` fields the vendor answers embedded on every answer, asked or not (its schema gives the object with no id
|
|
108
|
+
* alternative: Stripe's issuing card's `cardholder`): still stored as the id, hydrated from the current object */
|
|
109
|
+
alwaysEmbedded?: string[];
|
|
110
|
+
/** the vendor's own fields whose names begin with `_` (GitHub's `_links`, a HAL object's), which the vendor answers:
|
|
111
|
+
* answered like any field, where every other `_` field is the pack's bookkeeping and never answered */
|
|
112
|
+
vendorUnderscored?: string[];
|
|
113
|
+
/** Stored fields omitted from vendor views, without renaming them in retained state. Raw rows and
|
|
114
|
+
* ctx.own retain them for parent scope and semantics; get, rows, render and core answers omit them. */
|
|
115
|
+
viewOmit?: readonly string[];
|
|
116
|
+
/** fields the vendor answers as a list of the current children of another resource (Stripe's subscription `items`:
|
|
117
|
+
* its subscription_items), built on every answer from the child rows whose `by` field holds this id, in the order
|
|
118
|
+
* they were made, each through the child's own view and its embedding; never a stored copy. `list` is the list's own
|
|
119
|
+
* fields around `data`, where `{id}` is this resource's id and `"{count}"` the children's number */
|
|
120
|
+
collections?: Record<string, {
|
|
121
|
+
resource: string;
|
|
122
|
+
by: string;
|
|
123
|
+
list?: Record<string, unknown>;
|
|
124
|
+
}>;
|
|
104
125
|
/** this resource's deletion answer, when it is not the manifest's (`vector_store.deleted`) */
|
|
105
126
|
deleted?: unknown;
|
|
106
127
|
/** a child addressed under its parent: the path parameter naming the parent, the stored field that
|
|
@@ -117,6 +138,9 @@ export type ResourceDecl = {
|
|
|
117
138
|
resource: string;
|
|
118
139
|
allowDeleted?: boolean;
|
|
119
140
|
where?: Record<string, string>;
|
|
141
|
+
/** private fields a child observed under its parent keeps from the parent's parameters (`_jurisdiction:
|
|
142
|
+
* '{jurisdiction}'`), where the child's own read names none and a later read under it needs one ("Refresh") */
|
|
143
|
+
keep?: Record<string, string>;
|
|
120
144
|
};
|
|
121
145
|
/** a number the resource counts per parent (a repository's issue numbers, a thread's messages):
|
|
122
146
|
* the stored field, set on create to one past the highest among its siblings */
|
|
@@ -174,6 +198,10 @@ export type ResourceDecl = {
|
|
|
174
198
|
/** fields that name a subject as its id does (an organization by its id or its slug): a path's id and `ctx.find`
|
|
175
199
|
* match either */
|
|
176
200
|
alternateKeys?: string[];
|
|
201
|
+
/** fields that pair a subject a deploy settled with no vendor id with the vendor's copy a refresh observes (Slack's
|
|
202
|
+
* `channel_join` message, made by `conversations.join` and answered by no id: its `subtype` and `user`), where the
|
|
203
|
+
* `alternateKeys` do not; a subject missing one is never paired by them ("Refresh", adoption) */
|
|
204
|
+
adoptBy?: string[];
|
|
177
205
|
/** the list's search parameter (`query`): a row matches on an `exact` field's whole value or a `partial` field's
|
|
178
206
|
* substring, case-insensitively */
|
|
179
207
|
search?: {
|
|
@@ -182,24 +210,80 @@ export type ResourceDecl = {
|
|
|
182
210
|
partial?: string[];
|
|
183
211
|
};
|
|
184
212
|
/** fields that count this subject's children (an App's `installations_count`): the live subjects of `of` whose `by`
|
|
185
|
-
* holds this one's id, only those with `present` set when it is named
|
|
213
|
+
* holds this one's id (or vendor `parentKey`), only those with `present` set when it is named and without
|
|
214
|
+
* any matching `unless` field, plus `plus` (a customer's
|
|
186
215
|
* `next_invoice_sequence` is one past its numbered invoices). The kernel keeps each whenever a child is written. */
|
|
187
216
|
counts?: Record<string, {
|
|
188
217
|
of: string;
|
|
189
218
|
by: string;
|
|
219
|
+
parentKey?: string;
|
|
190
220
|
present?: string;
|
|
221
|
+
unless?: Record<string, unknown>;
|
|
191
222
|
plus?: number;
|
|
192
223
|
}>;
|
|
193
224
|
/** how the vendor's state of this type is read back into a root (the real-system adapters, "Refresh"): the list that
|
|
194
225
|
* enumerates it (once per parent, under `parent`; `complete: false` when it is not the whole type; `items`, the answer's
|
|
195
226
|
* path to them, when the spec does not name the list it answers), the one read of a singleton, or `none` with why the
|
|
196
|
-
* vendor offers no read-back. Every stored resource the vendor holds declares one.
|
|
197
|
-
|
|
227
|
+
* vendor offers no read-back. Every stored resource the vendor holds declares one. `{ get, known: true }`: the vendor
|
|
228
|
+
* lists no whole type, so the World's own subjects of it are each read again by `get` (a 404 is one gone), and what
|
|
229
|
+
* those reads observe anchors its children's lists; completeness is those subjects alone. */
|
|
230
|
+
/** `next`: where an answer names the next page's cursor (AWS's `NextToken`), sent back as `cursor` (the same name
|
|
231
|
+
* unless said) in the query, or in the body of a list asked by POST (an RPC list: AWS JSON's `x-amz-target`); a
|
|
232
|
+
* map of parameter to answer path where a page names several (S3's `key-marker` and `upload-id-marker`); `more`, the
|
|
233
|
+
* answer's flag that another page follows (S3's `IsTruncated`). `headers`: fixed headers of the list, `{name}` filled
|
|
234
|
+
* from the parent's parameters; `variants`: header sets each listed in turn, one type whole across them (R2's
|
|
235
|
+
* jurisdictions). A blob read by an `operation` (a GET of the unit's surface, filled from the subject's fields and
|
|
236
|
+
* its parent's parameters) keeps the bytes in the World's blobs, their key in `field`, and in `headersField` the
|
|
237
|
+
* answer's headers `keepHeaders` names (a name ending `*` a prefix: `x-amz-meta-*`), both fields private. */
|
|
238
|
+
refresh?: ({
|
|
198
239
|
list: string;
|
|
240
|
+
unpaginated?: true;
|
|
241
|
+
keyed?: true;
|
|
242
|
+
detail?: string;
|
|
243
|
+
detailMerge?: string;
|
|
244
|
+
detailWith?: Record<string, string>;
|
|
199
245
|
complete?: false;
|
|
200
246
|
items?: string;
|
|
247
|
+
shape?: RefreshShape;
|
|
248
|
+
next?: string | Record<string, string>;
|
|
249
|
+
nextLink?: {
|
|
250
|
+
header: string;
|
|
251
|
+
rel: string;
|
|
252
|
+
query: string;
|
|
253
|
+
when?: Record<string, string>;
|
|
254
|
+
};
|
|
255
|
+
cursor?: string;
|
|
256
|
+
more?: string;
|
|
201
257
|
} | {
|
|
202
258
|
get: string;
|
|
259
|
+
known?: true;
|
|
260
|
+
}) & {
|
|
261
|
+
params?: Record<string, string>;
|
|
262
|
+
headers?: Record<string, string>;
|
|
263
|
+
variants?: ReadonlyArray<{
|
|
264
|
+
headers: Record<string, string>;
|
|
265
|
+
}>;
|
|
266
|
+
blobs?: ReadonlyArray<{
|
|
267
|
+
path: string;
|
|
268
|
+
key: string;
|
|
269
|
+
resource?: string;
|
|
270
|
+
fields?: Record<string, string>;
|
|
271
|
+
} | {
|
|
272
|
+
operation: string;
|
|
273
|
+
field: string;
|
|
274
|
+
headers?: Record<string, string>;
|
|
275
|
+
headersField?: string;
|
|
276
|
+
keepHeaders?: string[];
|
|
277
|
+
}>;
|
|
278
|
+
query?: Record<string, string>;
|
|
279
|
+
idAs?: string;
|
|
280
|
+
graphql?: {
|
|
281
|
+
query: string;
|
|
282
|
+
variables?: Record<string, unknown>;
|
|
283
|
+
items: string;
|
|
284
|
+
pageInfo?: string;
|
|
285
|
+
cursor?: string;
|
|
286
|
+
};
|
|
203
287
|
} | {
|
|
204
288
|
none: string;
|
|
205
289
|
};
|
|
@@ -225,6 +309,15 @@ export type IngestDecl = {
|
|
|
225
309
|
types?: Record<string, {
|
|
226
310
|
resource: string;
|
|
227
311
|
deleted?: true;
|
|
312
|
+
/** where this type carries its object, when not at `object` (GitHub's `issue`, `pull_request`, `comment`) */
|
|
313
|
+
object?: string;
|
|
314
|
+
/** the JSON path of the value the resource's `parent.field` holds, when the event names its parent beside the object
|
|
315
|
+
* (GitHub's `repository.full_name`, the `{owner}/{repo}` its children are stored under) */
|
|
316
|
+
parent?: string;
|
|
317
|
+
/** where the object names the subject's id when not as the resource does (Resend's email events: `email_id`) */
|
|
318
|
+
id?: string;
|
|
319
|
+
/** the fields the event's type itself says (Resend's `email.delivered` is the email's `last_event: 'delivered'`) */
|
|
320
|
+
fields?: Record<string, unknown>;
|
|
228
321
|
}>;
|
|
229
322
|
/** an event answered instead of folded (Slack's url_verification): the body fields it matches, and the answer, a
|
|
230
323
|
* `$body.<path>` read from the event or a literal */
|
|
@@ -323,6 +416,14 @@ export type PerformHookArgs = {
|
|
|
323
416
|
};
|
|
324
417
|
export type PerformHook = (args: PerformHookArgs) => Promise<import('./head.js').PushOutcome>;
|
|
325
418
|
export type DerivedManifest = {
|
|
419
|
+
/** Vendor data-plane hosts mapped to an already-running customer guest. */
|
|
420
|
+
machineRoutes?: ReadonlyArray<{
|
|
421
|
+
host: string;
|
|
422
|
+
resource: string;
|
|
423
|
+
where: Record<string, string>;
|
|
424
|
+
name: string;
|
|
425
|
+
port: number | string;
|
|
426
|
+
}>;
|
|
326
427
|
/** The pack's descriptor, as data (docs/contributing/architecture.md, "The descriptor"), every field but `vendor`, which
|
|
327
428
|
* is the manifest's: the pack registers `packOf(manifest)`, so its index is a fixed file. A lane has none. */
|
|
328
429
|
descriptor?: Omit<PackDescriptor, 'vendor'>;
|
|
@@ -365,6 +466,14 @@ export type DerivedManifest = {
|
|
|
365
466
|
/** operations that only read though nothing in the spec says so (a POST that returns data):
|
|
366
467
|
* a read-only twin answers them */
|
|
367
468
|
reads?: string[];
|
|
469
|
+
/** operations of the vendor's API that set an account up rather than use it: an operator registering an OAuth client
|
|
470
|
+
* on the vendor's own admin routes, as a person makes settings on the vendor's site. Each is recorded as a door's
|
|
471
|
+
* write is (the World's own), so a deploy never offers it to the vendor and the vendor-backed acceptance holds it as
|
|
472
|
+
* what the account already has; `why` says who performs it and where */
|
|
473
|
+
accountSetup?: Array<{
|
|
474
|
+
operation: string;
|
|
475
|
+
why: string;
|
|
476
|
+
}>;
|
|
368
477
|
/** how the vendor writes an instant: Unix seconds, Unix milliseconds (Clerk's `created_at`), or ISO 8601 */
|
|
369
478
|
time: 'unix' | 'unix-ms' | 'iso';
|
|
370
479
|
/** the vendor's CORS, as its gateway answers a browser (cors.ts): the pack's fetch is served behind `withCors` */
|
|
@@ -399,7 +508,8 @@ export type DerivedManifest = {
|
|
|
399
508
|
error: ErrorSpec;
|
|
400
509
|
};
|
|
401
510
|
/** request headers that carry meaning to the vendor (a tenant header such as `Stripe-Account`): recorded with a write
|
|
402
|
-
* so its perform sends them again (the real-system adapters, "What a pack declares"); `version.header` is too
|
|
511
|
+
* so its perform sends them again (the real-system adapters, "What a pack declares"); `version.header` is too. A name
|
|
512
|
+
* ending `*` is a prefix: every header it begins (S3's `x-amz-meta-*`, an object's own metadata). */
|
|
403
513
|
headers?: string[];
|
|
404
514
|
/** the vendor's signed webhooks, folded into a root */
|
|
405
515
|
ingest?: IngestDecl;
|
|
@@ -422,13 +532,14 @@ export type DerivedManifest = {
|
|
|
422
532
|
notFound: {
|
|
423
533
|
status: number;
|
|
424
534
|
message: string;
|
|
425
|
-
code?: string;
|
|
535
|
+
code?: string | number;
|
|
426
536
|
kind?: string;
|
|
427
537
|
withParam?: boolean;
|
|
428
538
|
};
|
|
429
539
|
/** the list envelope (placeholders `{data}`, `{has_more}`, `{url}`, `{first_id}`, `{last_id}`),
|
|
430
|
-
* its page size, its cursors, and where an unknown cursor starts: the first page or past the end
|
|
431
|
-
|
|
540
|
+
* its page size, its cursors, and where an unknown cursor starts: the first page or past the end.
|
|
541
|
+
* Absent when the unit serves no stored list; the core does not own lists without this declaration. */
|
|
542
|
+
list?: {
|
|
432
543
|
style: 'envelope';
|
|
433
544
|
envelope: unknown;
|
|
434
545
|
limit: {
|
|
@@ -444,8 +555,18 @@ export type DerivedManifest = {
|
|
|
444
555
|
cursor?: {
|
|
445
556
|
param: string;
|
|
446
557
|
encoding: 'base64-offset';
|
|
558
|
+
} | {
|
|
559
|
+
param: string;
|
|
560
|
+
encoding: 'offset-template';
|
|
561
|
+
template: string;
|
|
562
|
+
link: {
|
|
563
|
+
previous: string;
|
|
564
|
+
next: string;
|
|
565
|
+
results: string;
|
|
566
|
+
cursor: string;
|
|
567
|
+
};
|
|
447
568
|
};
|
|
448
|
-
/** numbered pages (1-based
|
|
569
|
+
/** numbered pages (1-based, the size in `limit.param`), with the vendor's `Link` header
|
|
449
570
|
* naming the first, previous, next and last pages (`link`); the envelope may name `{total_count}` and `{max_page}` */
|
|
450
571
|
page?: {
|
|
451
572
|
param: string;
|
|
@@ -526,17 +647,30 @@ export type DerivedManifest = {
|
|
|
526
647
|
/** operations that check a credential of their own, not the account's (Cloudflare's asset upload reads its upload
|
|
527
648
|
* session's JWT from the same header): the gate leaves them to their handler */
|
|
528
649
|
exempt?: string[];
|
|
650
|
+
/** ordered API-skin error wires, selected before scenario matching and ordinary routing */
|
|
651
|
+
wires?: Array<{
|
|
652
|
+
paths: string;
|
|
653
|
+
error: DerivedManifest['error'];
|
|
654
|
+
missing?: ErrorSpec;
|
|
655
|
+
invalid?: ErrorSpec;
|
|
656
|
+
}>;
|
|
529
657
|
/** the vendor checks the key before it routes: a path it does not have is refused a missing or invalid key first */
|
|
530
658
|
beforeRouting?: boolean;
|
|
531
659
|
};
|
|
532
660
|
/** the twin door that makes the next request answer the vendor's rate-limit refusal */
|
|
533
|
-
/** headers every answer carries (a request id)
|
|
661
|
+
/** headers every answer carries (a request id); a value's `{hex:N}` is filled per answer, from the World's count of
|
|
662
|
+
* answers (so a second World answers the same ids in the same order), unless the handler set the header itself */
|
|
534
663
|
answerHeaders?: Record<string, string>;
|
|
535
664
|
/** an origin the pack writes into URLs it mints, rewritten in every JSON answer to where this
|
|
536
665
|
* twin is reached for the request (twinPublicBase) */
|
|
537
666
|
origin?: {
|
|
538
667
|
placeholder: string;
|
|
539
668
|
};
|
|
669
|
+
/** Disclosed local connection fields, separate from vendor response schemas. */
|
|
670
|
+
worldFields?: Record<string, Record<string, {
|
|
671
|
+
type: 'array' | 'object' | 'string' | 'number' | 'boolean';
|
|
672
|
+
why: string;
|
|
673
|
+
}>>;
|
|
540
674
|
resources: Record<string, ResourceDecl>;
|
|
541
675
|
/** Read-only cross-pack credential subjects of the same vendor (architecture A3); no root is exposed to handlers. */
|
|
542
676
|
ownerReads?: ReadonlyArray<{
|
|
@@ -608,9 +742,22 @@ export type DerivedManifest = {
|
|
|
608
742
|
* matched at the path's start: stripped before routing, so the operation it names is the one served. Its named groups
|
|
609
743
|
* (Jira's `/ex/jira/(?<cloudId>[^/]+)`) are the operation's parameters as well. */
|
|
610
744
|
pathPrefix?: string;
|
|
745
|
+
/** A prefix the vendor serves as its own base path (Discord answers `/api` and `/api/v9` as `/api/v10`, the spec's), as
|
|
746
|
+
* a regular expression matched at the path's start: put in place of the surface's base path before routing, so an
|
|
747
|
+
* operation compiled under the spec's base answers each. Perform and refresh send the spec's base, as the SDK does. */
|
|
748
|
+
basePathAlias?: string;
|
|
611
749
|
/** A pattern over the request's vendor host whose named groups are the operation's parameters (E2B's envd answers each
|
|
612
750
|
* sandbox at `49983-<sandboxID>.e2b.app`: `^\\d+-(?<sandboxID>[a-z0-9]+)\\.`). */
|
|
613
751
|
hostParams?: string;
|
|
752
|
+
/** The vendor host a lane's calls go to when it carries the call's parameters (R2's `<account>.r2.cloudflarestorage.com`):
|
|
753
|
+
* `{name}` filled from the call's parameters, `values` a parameter's literal in the host (the real-system adapters,
|
|
754
|
+
* "Lanes"). Perform and refresh send to `https://<host><path>`. */
|
|
755
|
+
remoteHost?: {
|
|
756
|
+
template: string;
|
|
757
|
+
values?: Record<string, Record<string, string>>;
|
|
758
|
+
};
|
|
759
|
+
/** Named operation parameters from vendor routing headers (shared-host compute services). */
|
|
760
|
+
headerParams?: Record<string, string>;
|
|
614
761
|
/** The persistent wires the vendor's clients hold open (sockets.ts: Discord's Gateway): each served at its path by
|
|
615
762
|
* the pack's `semantics/sockets.ts`, which the kernel offers every write after its webhooks. */
|
|
616
763
|
sockets?: ReadonlyArray<SocketDecl>;
|
|
@@ -658,14 +805,6 @@ export declare function strictFields(m: DerivedManifest, operation: DerivedOpera
|
|
|
658
805
|
};
|
|
659
806
|
/** A value as the vendor reads a boolean (`ctx.flag`, the manifest's `booleans`). */
|
|
660
807
|
export declare function flagOf(m: Pick<DerivedManifest, 'booleans'>, value: unknown): boolean | undefined;
|
|
661
|
-
/** A form body's bracket notation (`a[b][0][c]=v`, `expand[]=x`) as nested objects and arrays. A form carries only
|
|
662
|
-
* text: a field the operation's spec types as a number or a boolean (`scalars`, by bracket path, written by
|
|
663
|
-
* world-tooling's formScalarsOf) is read as one when its text is that literal; every other field stays the text sent
|
|
664
|
-
* (`metadata[order]=007`, `name=2024`). */
|
|
665
|
-
/** A field set as the object's own, whatever its name (`__proto__`, `constructor` and `prototype` are data a caller
|
|
666
|
-
* may name: Stripe's metadata keys are the caller's), never through what the object inherits. */
|
|
667
|
-
export declare function ownField(node: Record<string, unknown> | unknown[], key: string, value: unknown): void;
|
|
668
|
-
export declare function parseBracketForm(text: string, scalars?: Readonly<Record<string, string | undefined>>): Record<string, unknown>;
|
|
669
808
|
/** A request's parameters, its query's and its body's. With the manifest's `body.form.coerce`, a form's fields the
|
|
670
809
|
* operation's spec types as numbers or booleans are read as them (parseBracketForm); without an operation (a twin door)
|
|
671
810
|
* every form value is its text. */
|
|
@@ -678,19 +817,34 @@ export declare function resourcesOfType(service: string, type: string, root?: st
|
|
|
678
817
|
/** The vendor's view of a stored subject: its own fields, bookkeeping (`_`) left out. */
|
|
679
818
|
/** A stored subject as the vendor's object: its id first (the subject's, unless the pack kept an id of its own), then
|
|
680
819
|
* the fields the pack wrote, bookkeeping (`_`) and the kernel's updatedAt left out. */
|
|
681
|
-
export declare function render(r: TwinResource): Record<string, unknown>;
|
|
820
|
+
export declare function render(r: TwinResource, vendorUnderscored?: readonly string[]): Record<string, unknown>;
|
|
682
821
|
/** Where the core runs: the World root it reads and writes, and its clock (the World's by default;
|
|
683
822
|
* a caller that pins an instant passes its own). */
|
|
684
823
|
/** One call of a protocol-3 pack's default data (`src/semantics/seed.ts` exports `seed: SeedCall[]`): a request to the
|
|
685
824
|
* vendor's own operation (or the pack's door), made in order against the twin by the runner `volter-world init` writes
|
|
686
825
|
* beside the copied data. An ordinary path is relative to the twin base. A call naming a browser uses the
|
|
687
826
|
* vendor's absolute URL and is exported separately as `browserSeed`, after the ordinary `seed` calls. */
|
|
827
|
+
/** How a refresh list's answer items become subjects' fields where each is not one subject's object (architecture,
|
|
828
|
+
* "Refresh"): `scalar`, a bare item is that field; `value` (with `keyed`), a scalar map value is that field and, with
|
|
829
|
+
* `keyAs`, the map key is that field rather than the id; `spread`, an item expands into the array at `path`, each
|
|
830
|
+
* element an object or a scalar named `as`, beside the item's fields `carry` names (field: path in the item). */
|
|
831
|
+
export type RefreshShape = {
|
|
832
|
+
scalar?: string;
|
|
833
|
+
value?: string;
|
|
834
|
+
keyAs?: string;
|
|
835
|
+
spread?: {
|
|
836
|
+
path: string;
|
|
837
|
+
as?: string;
|
|
838
|
+
carry?: Record<string, string>;
|
|
839
|
+
};
|
|
840
|
+
};
|
|
688
841
|
export type SeedCall = {
|
|
689
842
|
browser?: string;
|
|
690
843
|
method: string;
|
|
691
844
|
path: string;
|
|
692
845
|
body?: unknown;
|
|
693
|
-
headers?: Record<string, string>;
|
|
846
|
+
headers?: Record<string, string>; /** the instant the account made it, before the World's time: the call is made with the World clock frozen there */
|
|
847
|
+
at?: string;
|
|
694
848
|
};
|
|
695
849
|
/** Where a call is answered: the World's root, its clock, and the managed Postgres the runtime binds to the pack
|
|
696
850
|
* (`database`, the descriptor's `managedDatabase`), which a handler reaches as `ctx.engine` — READ ONLY in every
|
|
@@ -710,9 +864,18 @@ export declare const LANE_HEADER = "x-volter-lane";
|
|
|
710
864
|
/** What a coverage measurement sees of a pack's declared state logic: each move a request made and each refusal a
|
|
711
865
|
* guard gave, by the transition that decided it. Nothing is observed unless a measurement installs an observer
|
|
712
866
|
* (scripts/life-coverage.ts); serving never depends on it. */
|
|
713
|
-
export type
|
|
867
|
+
export type TransitionEntry = {
|
|
868
|
+
action: TwinAction;
|
|
869
|
+
field: string;
|
|
870
|
+
actor: Actor;
|
|
871
|
+
};
|
|
872
|
+
export type TransitionObserver = (decl: StateField, transition: Transition, outcome: 'moved' | 'refused', from: string, entry?: TransitionEntry) => void;
|
|
714
873
|
export declare function observeTransitions(observer: TransitionObserver | undefined): void;
|
|
715
|
-
|
|
874
|
+
/** The transition a request asks for on one state field, or the vendor's refusal when none applies. */
|
|
875
|
+
/** What a declared machine says to one move: the transition that allows it, or the refusal it gives (and
|
|
876
|
+
* nothing when it declares neither). The derived core and `legal` ask it; so does an engine that is not
|
|
877
|
+
* HTTP-shaped (a line protocol's session), so one machine rules every wire. */
|
|
878
|
+
export declare function transitionFor(field: string, decl: StateField, operationId: string, current: unknown, requested: unknown, id?: string, actor?: Actor, entry?: TransitionEntry): {
|
|
716
879
|
move?: Transition;
|
|
717
880
|
refusal?: ErrorSpec;
|
|
718
881
|
};
|
|
@@ -747,14 +910,11 @@ export type SemanticsContext = {
|
|
|
747
910
|
/** What the World's scenario decided for this turn (a model vendor's answer: the handler matched, or the miss), on an
|
|
748
911
|
* operation the pack's `semantics/scenario.ts` names; undefined elsewhere, or when the World carries no scenario. */
|
|
749
912
|
scenario: ScenarioDecision | undefined;
|
|
750
|
-
/** A message the vendor sends the application's own server that no declared event is (a push notification), through
|
|
751
|
-
* the World's route and egress rule: the receiver's status, or 0 when refused or unreachable. */
|
|
752
|
-
deliver(url: string, init: RequestInit): Promise<number>;
|
|
753
913
|
/** A message the vendor sends the application's server and decides by its answer, waited on for at most `within`
|
|
754
914
|
* milliseconds (a real-time authorization request): its status and body, or why there was none. */
|
|
755
915
|
ask(url: string, init: RequestInit, within: number): Promise<ApplicationAnswer>;
|
|
756
916
|
/** A git repository of the World, by the pack's name for it (the git plane, world-core git/): its objects in the
|
|
757
|
-
* World's content-addressed object store
|
|
917
|
+
* World's repository-scoped content-addressed object store, its refs in the World's store. Served over smart HTTP
|
|
758
918
|
* (`git.serveSmartHttp`), read and written through the library's codecs. */
|
|
759
919
|
git(name: string): {
|
|
760
920
|
store: GitObjectStore;
|
|
@@ -772,6 +932,8 @@ export type SemanticsContext = {
|
|
|
772
932
|
/** who is calling, when the manifest says how to tell */
|
|
773
933
|
actor: string | undefined;
|
|
774
934
|
now(): unknown;
|
|
935
|
+
/** Render a stored row or vendor view using its resource declaration, retaining the stored subject id fallback. */
|
|
936
|
+
render(row: Record<string, unknown>, resource?: string): Record<string, unknown>;
|
|
775
937
|
get(resource: string, id: string): Record<string, unknown> | undefined;
|
|
776
938
|
/** One credential subject in a manifest-declared owner's World store. Ambiguous stores refuse the read. */
|
|
777
939
|
ownerRow(owner: string, resource: string, id: string): Record<string, unknown> | undefined;
|
|
@@ -782,6 +944,11 @@ export type SemanticsContext = {
|
|
|
782
944
|
issue(resource: string): Promise<string>;
|
|
783
945
|
/** The vendor's open sessions of one of its sockets in this World (a request answered by a session: sockets.ts). */
|
|
784
946
|
sockets(id: string): SocketSession[];
|
|
947
|
+
/** Hold this read until the World writes (held-reads.ts: HTTP long polling): true when a write of one of the named
|
|
948
|
+
* resources lands in this World, false when `ms` pass or the client hangs up; at once false in a read-only World. */
|
|
949
|
+
awaitWrite(resources: ReadonlyArray<string>, ms: number): Promise<boolean>;
|
|
950
|
+
/** Observe a condition until it holds or the caller's timeout/cancellation, waking on writes and pollMs. */
|
|
951
|
+
awaitCondition(resources: ReadonlyArray<string>, ms: number, pollMs: number, condition: () => Promise<boolean>): Promise<boolean>;
|
|
785
952
|
/** A secret for `label` (an app's client secret, a store's read token): an HMAC under a seed the World makes once, at
|
|
786
953
|
* random, and keeps as bookkeeping no door answers. The same label gives the same secret for the World's whole life,
|
|
787
954
|
* and no one can compute it from ids the World shows, as they can a value derived from them alone. */
|
|
@@ -802,6 +969,15 @@ export type SemanticsContext = {
|
|
|
802
969
|
privatePem: string;
|
|
803
970
|
publicPem: string;
|
|
804
971
|
} | undefined;
|
|
972
|
+
/** Allocate a stored occurrence and append its fields under one action lock. The optional field factory is pure. */
|
|
973
|
+
create(resource: string, fields: Record<string, unknown> | ((id: string) => Record<string, unknown>), operation: string): Promise<Record<string, unknown>>;
|
|
974
|
+
/** Create under declared unique keys and the action lock; a collision returns the existing own-field view without a write. */
|
|
975
|
+
createUnique(resource: string, fields: Record<string, unknown> | ((id: string) => Record<string, unknown>), operation: string): Promise<{
|
|
976
|
+
created: boolean;
|
|
977
|
+
row: Record<string, unknown>;
|
|
978
|
+
}>;
|
|
979
|
+
/** Decide an update from the current live stored row under the action lock; undefined leaves it unchanged. */
|
|
980
|
+
change(resource: string, id: string, decide: (row: Record<string, unknown>) => Record<string, unknown> | undefined, operation: string): Promise<Record<string, unknown> | undefined>;
|
|
805
981
|
write(resource: string, id: string, fields: Record<string, unknown>, operation: string): Promise<Record<string, unknown>>;
|
|
806
982
|
/** Add numeric deltas to an existing bookkeeping row under the kernel's atomic write seam. */
|
|
807
983
|
accumulate(resource: string, id: string, deltas: Record<string, number>, operation: string): Promise<void>;
|
|
@@ -834,8 +1010,8 @@ export type SemanticsContext = {
|
|
|
834
1010
|
fields?: Record<string, unknown>;
|
|
835
1011
|
occurredAt?: string;
|
|
836
1012
|
}>;
|
|
837
|
-
/** Write
|
|
838
|
-
record(type: string, fields: Record<string, unknown>, id?: string): Promise<string>;
|
|
1013
|
+
/** Write bookkeeping without the incoming request; an explicit operation observes its checked state move. Mint an id when none is given. */
|
|
1014
|
+
record(type: string, fields: Record<string, unknown>, id?: string, operation?: string): Promise<string>;
|
|
839
1015
|
/** Decide a write from the tree as it stands and make it, with nothing written between the read
|
|
840
1016
|
* and the write (a minted number, a first poll that moves a subject). `decide` returns the write,
|
|
841
1017
|
* or nothing to write; the answer is its `value`. */
|
|
@@ -859,6 +1035,8 @@ export type SemanticsContext = {
|
|
|
859
1035
|
/** Validate the request body's top-level derived schema under body.validation, before a write. */
|
|
860
1036
|
validate(): Response | undefined;
|
|
861
1037
|
refuse(e: ErrorSpec): Response;
|
|
1038
|
+
/** Answer the manifest's declared unserved capability gap. */
|
|
1039
|
+
gap(): Response;
|
|
862
1040
|
notFound(resource: string, id: string, param?: string): Response;
|
|
863
1041
|
reply(body: unknown, status?: number): Response;
|
|
864
1042
|
/** Answer in the vendor's success envelope under this operation's key (`{ ok: true, channel }`). */
|
|
@@ -948,7 +1126,7 @@ export type HandlerContext = Omit<SemanticsContext, 'now' | 'core' | 'atomically
|
|
|
948
1126
|
};
|
|
949
1127
|
/** What a write hook reads: the writing call's context without its ways to write, so a hook that renders an event
|
|
950
1128
|
* cannot write again (and run itself again). */
|
|
951
|
-
export type WriteHookContext = Omit<HandlerContext, 'write' | 'record' | 'accumulate' | 'at' | 'over'>;
|
|
1129
|
+
export type WriteHookContext = Omit<HandlerContext, 'write' | 'create' | 'createUnique' | 'change' | 'issue' | 'record' | 'accumulate' | 'at' | 'over'>;
|
|
952
1130
|
/** A derived pack's handler: one operation, by its operationId, over the contract's context. */
|
|
953
1131
|
export type Handler = (ctx: HandlerContext) => Promise<Response>;
|
|
954
1132
|
/** The context the kernel opens for a call (a handler's, a door's, a screen's). Kernel-internal: packs are given it. */
|
|
@@ -977,7 +1155,7 @@ export declare function crossCutting(m: DerivedManifest, opts?: CoreScope & {
|
|
|
977
1155
|
* coming (another wire's mutation, a door, a screen) — and answered with the vendor's own read-only
|
|
978
1156
|
* error; `GET /twin` advertises `requestScopes`. The pack's catch-up runs under `runAsVendorMove`
|
|
979
1157
|
* (request-scope.ts), so time's moves still land when a read-only request is what arrives. */
|
|
980
|
-
export declare function derivedRequestScopes<F extends (request: Request) => Promise<Response>>(m: DerivedManifest, fetch: F): F;
|
|
1158
|
+
export declare function derivedRequestScopes<F extends (request: Request) => Promise<Response>>(m: DerivedManifest, fetch: F, readOnly?: boolean): F;
|
|
981
1159
|
/** A semantics context for a request no surface operation names: another wire's (GraphQL) resolvers
|
|
982
1160
|
* get the same interface as a handler, named by the operation id the wire gives. */
|
|
983
1161
|
export declare function semanticsContext(m: DerivedManifest, request: Request, operation: DerivedOperation, scope?: CoreScope): Promise<SemanticsContext>;
|