Compare commits
6 Commits
aadc35581d
...
exported
| Author | SHA1 | Date | |
|---|---|---|---|
| b0d31ba51c | |||
| 2dffdbcd9f | |||
| c9265e7903 | |||
| a05f58f7fe | |||
| 93c8cae1e6 | |||
| 5a611bbc9b |
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"sourceRepo": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos",
|
||||
"sourceCommit": "1c2dbc6ca2c3917292f158cbbaef531836eaacca",
|
||||
"sourceCommit": "c87835bff85794bc232dbaaddc1eb3b593c2aab8",
|
||||
"sourcePath": "quixos-protocol",
|
||||
"exportName": "quixos-protocol",
|
||||
"mirrorRemote": "https://gitea-external.egads.tutti.syntaxblitz.net/quixos/quixos-protocol.git"
|
||||
|
||||
@@ -408,6 +408,9 @@ identifier
|
||||
| POLL
|
||||
| RPC
|
||||
| QUERYABLE
|
||||
| RESULT_BYTES
|
||||
| RPC_CALLS
|
||||
| DEADLINE_MS
|
||||
;
|
||||
|
||||
stringLiteral
|
||||
@@ -415,6 +418,9 @@ stringLiteral
|
||||
;
|
||||
|
||||
WORKSPACE: 'workspace';
|
||||
RESULT_BYTES: 'result-bytes';
|
||||
RPC_CALLS: 'rpc-calls';
|
||||
DEADLINE_MS: 'deadline-ms';
|
||||
QUERY: 'query';
|
||||
SPECIALIZE: 'specialize';
|
||||
ROOT: 'root';
|
||||
|
||||
@@ -3,6 +3,7 @@ syntax = "proto3";
|
||||
package camino;
|
||||
|
||||
import "camino/schema.proto";
|
||||
import "quixos/refs.proto";
|
||||
|
||||
service CaminoService {
|
||||
rpc ExecuteQuery(QueryRequest) returns (QueryResponse);
|
||||
@@ -69,6 +70,27 @@ message Value {
|
||||
CrdtValue crdt_value = 10;
|
||||
}
|
||||
ValueSource source = 11;
|
||||
// Trusted query coordinator annotation. Travels with values through residual
|
||||
// row selection, then is removed in favor of final-path hydration metadata.
|
||||
QueryFieldOrigin query_origin = 12;
|
||||
}
|
||||
|
||||
message QueryFieldOrigin {
|
||||
string selection_id = 1;
|
||||
string atom_id = 2;
|
||||
string interface_revision_id = 3;
|
||||
string member_id = 4;
|
||||
StateValueSource source = 5;
|
||||
}
|
||||
message QueryLiveField {
|
||||
repeated QueryPathPart path = 1;
|
||||
string selection_id = 2;
|
||||
string object_id = 3;
|
||||
quixos.CapabilityRef capability = 4;
|
||||
string watch_operation_id = 5;
|
||||
string setter_operation_id = 6;
|
||||
quixos.FieldEditing editing = 7;
|
||||
StateValueSource source = 8;
|
||||
}
|
||||
|
||||
message InstallPersistencePlanRequest {
|
||||
@@ -256,6 +278,7 @@ message QueryStats {
|
||||
uint32 relational_stages = 8;
|
||||
uint32 captured_candidates = 9;
|
||||
double relational_ms = 10;
|
||||
double residual_ms = 11;
|
||||
}
|
||||
message QueryResponse {
|
||||
Value value = 1;
|
||||
@@ -270,6 +293,7 @@ message QueryResponse {
|
||||
// Native reads share one database snapshot; package enrichment does not.
|
||||
string consistency = 9; // native-snapshot | mixed
|
||||
repeated QueryRelationalCapture relational_captures = 10;
|
||||
repeated QueryLiveField live_fields = 11;
|
||||
}
|
||||
|
||||
// Private coordinator input, removed before publishing a result. Memberships
|
||||
|
||||
@@ -104,6 +104,8 @@ message QuerySelection {
|
||||
repeated QuerySelection selection = 8;
|
||||
QueryRelationalPlan relational = 9;
|
||||
QueryPredicate predicate = 10;
|
||||
// Stable checked selection identity; empty for ordinary value projections.
|
||||
string live_selection_id = 11;
|
||||
}
|
||||
// Resolved IDs, not GraphQL names, determine execution. Response selections
|
||||
// remain separate so aliases and fragments cannot change relational semantics.
|
||||
|
||||
@@ -87,20 +87,16 @@ message InvokeCapabilityResponse {
|
||||
FieldEditing field_editing = 7;
|
||||
}
|
||||
|
||||
// Resolved from the checked native getter/setter binding, not Value.source.
|
||||
message FieldEditing {
|
||||
string getter_operation_id = 1;
|
||||
string setter_operation_id = 2;
|
||||
string document_type = 3;
|
||||
string binding_digest = 4;
|
||||
}
|
||||
message EditCapabilityFieldRequest {
|
||||
// The public getter; setter must belong to the same value member.
|
||||
quixos.CapabilityRef capability = 1;
|
||||
string object_id = 2;
|
||||
string setter_operation_id = 3;
|
||||
string binding_digest = 4;
|
||||
oneof edit {
|
||||
camino.CrdtValue update = 5;
|
||||
camino.Value replacement = 7;
|
||||
}
|
||||
string client_mutation_id = 6;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,20 @@ message CapabilityRef {
|
||||
ConformanceWitness conformance = 3;
|
||||
}
|
||||
|
||||
// Resolved native editing semantics. A source snapshot alone grants no writer.
|
||||
message FieldEditing {
|
||||
string getter_operation_id = 1;
|
||||
string setter_operation_id = 2;
|
||||
string document_type = 3;
|
||||
string binding_digest = 4;
|
||||
enum Mode {
|
||||
UNSPECIFIED = 0;
|
||||
REGISTER = 1;
|
||||
CRDT = 2;
|
||||
}
|
||||
Mode mode = 5;
|
||||
}
|
||||
|
||||
message ConformanceWitness {
|
||||
string object_id = 1;
|
||||
string interface_revision_id = 2;
|
||||
|
||||
@@ -5,6 +5,8 @@ declare module "@quixos/web-studio-react-runtime" {
|
||||
import type * as React from "react";
|
||||
export function useComponentOverlayContainer(): HTMLElement;
|
||||
export function useComponentStyleRoot(): ShadowRoot;
|
||||
/** Aggregate transport counters only; contains no object identities or values. */
|
||||
export function getFieldTransportMetrics(): Partial<Record<"get" | "watch" | "register" | "crdt" | "setter", Readonly<{started: number; active: number; completed: number; failed: number; totalMs: number}>>>;
|
||||
export type ObjectRef<AtomId extends string> = string & {
|
||||
readonly $quixosAtom: AtomId;
|
||||
};
|
||||
@@ -22,8 +24,9 @@ declare module "@quixos/web-studio-react-runtime" {
|
||||
export function useTryConform<View>(object: string | {readonly $quixosRef: string}, contract: ReactInterfaceContract<View>): ConformanceResult<View>;
|
||||
export type QueryValueType = {kind: "builtin" | "scalar"; name: string} | {kind: "record"; fields: Record<string, QueryValueType>} | {kind: "optional" | "list"; value: QueryValueType} | {kind: "object-ref"; expectation: {kind: "atom"; atomId: string} | {kind: "interface"; interfaceRevisionId: string}};
|
||||
export type QueryReference<Contract extends string = string> = {readonly $quixosRef: string; readonly queryContract: Contract};
|
||||
export interface QueryDescriptor<Variables, Result> {readonly id: string; readonly definitionDigest: string; readonly rootInterfaceRevisionId: string; readonly variables: QueryValueType; readonly output: QueryValueType; readonly watch: boolean; readonly $types?: (variables: Variables, result: Result) => [Variables, Result]}
|
||||
export type QueryPartial<T> = T extends QueryReference ? T : T extends readonly (infer Item)[] ? QueryPartial<Item>[] : T extends object ? {[Key in keyof T]?: QueryPartial<T[Key]>} : T;
|
||||
export type QueryLiveProjection = {path: readonly string[]; selectionId: string; interfaceRevisionId: string; getOperationId: string; setOperationId?: string; watchOperationId?: string; inputKind: "fields" | "value"; valueType: QueryValueType; conditions: {include: boolean; defaultValue?: boolean; value: {kind: "variable"; name: string} | {kind: "literal"; value: unknown}}[]};
|
||||
export interface QueryDescriptor<Variables, Result> {readonly id: string; readonly definitionDigest: string; readonly rootInterfaceRevisionId: string; readonly variables: QueryValueType; readonly output: QueryValueType; readonly watch: boolean; readonly liveFields?: readonly QueryLiveProjection[]; readonly $types?: (variables: Variables, result: Result) => [Variables, Result]}
|
||||
export type QueryPartial<T> = T extends {readonly $quixosRef: string} | {readonly capability: {readonly getOperationId: string}} ? T : T extends readonly (infer Item)[] ? QueryPartial<Item>[] : T extends object ? {[Key in keyof T]?: QueryPartial<T[Key]>} : T;
|
||||
export type QueryFieldState = {path: readonly (string | number)[]; status: "pending" | "error"; error?: string};
|
||||
export type QueryState<T> = {refreshing: boolean; fields: QueryFieldState[]; runId?: string; sequence?: bigint; consistency?: string} & ({status: "loading"; data?: undefined; error?: undefined} | {status: "ready"; data: T; error?: undefined} | {status: "partial"; data: QueryPartial<T>; error?: undefined} | {status: "error"; data?: T | QueryPartial<T>; error: Error});
|
||||
export function useQuery<Variables, Result>(descriptor: QueryDescriptor<Variables, Result>, options: {root: string | {readonly $quixosRef: string}; variables: Variables}): QueryState<Result> & {refresh(): void};
|
||||
@@ -55,8 +58,12 @@ declare module "@quixos/web-studio-react-runtime" {
|
||||
options?: {clientMutationId?: string; signal?: AbortSignal},
|
||||
) => Promise<Result>;
|
||||
export const h: typeof React.createElement;
|
||||
export function useLiveField<T>(field: ReadableField<T>, options: {write: (value: T) => Promise<void>}): readonly [T, (value: T) => Promise<void>];
|
||||
export function useLiveField<T>(field: WritableField<T>): readonly [T, (value: T) => Promise<void>];
|
||||
export function useLiveField<T>(field: ReadableField<T>): readonly [T];
|
||||
export type LiveFieldState<T> = {refreshing: boolean; stale: boolean; pendingWrites: number; writeError?: Error; refresh(): Promise<void>; discard(): void} & ({status: "loading"; value?: undefined; error?: undefined} | {status: "ready"; value: T; error?: Error} | {status: "error"; value?: undefined; error: Error});
|
||||
export type WritableLiveFieldState<T> = LiveFieldState<T> & {set(value: T): Promise<void>; retry(): Promise<void>};
|
||||
export function useLiveField<T>(field: ReadableField<T>, options: {id: string; write: (value: T) => Promise<void>}): WritableLiveFieldState<T>;
|
||||
export function useLiveField<T>(field: WritableField<T>): WritableLiveFieldState<T>;
|
||||
export function useLiveField<T>(field: ReadableField<T>): LiveFieldState<T>;
|
||||
export function useSuspenseLiveField<T>(field: WritableField<T>): WritableLiveFieldState<T> & {status: "ready"; value: T};
|
||||
export function useSuspenseLiveField<T>(field: ReadableField<T>): LiveFieldState<T> & {status: "ready"; value: T};
|
||||
}
|
||||
`;
|
||||
|
||||
+19
-1
@@ -1,5 +1,6 @@
|
||||
import type { BindingSchema } from "./index.js";
|
||||
import type { ValueType } from "../capability-model/types.js";
|
||||
import { queryPresentation } from "../query/presentation.js";
|
||||
|
||||
/** Browser projection of the SAME checked RPC types, not a second props schema. */
|
||||
export function generateReactBindings(
|
||||
@@ -128,9 +129,25 @@ export function generateReactBindings(
|
||||
return type(value);
|
||||
};
|
||||
const queries = pkg.checkedQueries ?? [];
|
||||
const presentedType = (
|
||||
value: ValueType,
|
||||
fields: ReturnType<typeof queryPresentation>,
|
||||
path: string[] = [],
|
||||
): string => {
|
||||
const field = fields.find((field) => JSON.stringify(field.path) === JSON.stringify(path));
|
||||
if (field)
|
||||
return `${field.conditions.length ? "(" : ""}${field.setOperationId ? "WritableField" : "ReadableField"}<${type(field.valueType)}>${field.conditions.length ? " | null)" : ""}`;
|
||||
if (value.kind === "optional") return `(${presentedType(value.value, fields, path)} | null)`;
|
||||
if (value.kind === "list") return `Array<${presentedType(value.value, fields, [...path, "*"])}>`;
|
||||
if (value.kind === "record")
|
||||
return `{${Object.entries(value.fields)
|
||||
.map(([key, child]) => `${q(key)}: ${presentedType(child, fields, [...path, key])}`)
|
||||
.join(";")}}`;
|
||||
return queryType(value);
|
||||
};
|
||||
const queryCode =
|
||||
`export type QueryVariables = {${queries.map((query) => `${q(query.declaration.displayName)}: ${queryType(query.variables)}`).join(";")}};\n` +
|
||||
`export type QueryResults = {${queries.map((query) => `${q(query.declaration.displayName)}: ${queryType(query.output)}`).join(";")}};\n` +
|
||||
`export type QueryResults = {${queries.map((query) => `${q(query.declaration.displayName)}: ${presentedType(query.output, queryPresentation(query, schema.interfaces))}`).join(";")}};\n` +
|
||||
`export const queries: {${queries.map((query) => `${q(query.declaration.displayName)}: QueryDescriptor<QueryVariables[${q(query.declaration.displayName)}], QueryResults[${q(query.declaration.displayName)}]>`).join(";")}} = ${JSON.stringify(
|
||||
Object.fromEntries(
|
||||
queries.map((query) => [
|
||||
@@ -141,6 +158,7 @@ export function generateReactBindings(
|
||||
rootInterfaceRevisionId: query.declaration.root,
|
||||
variables: query.variables,
|
||||
output: query.output,
|
||||
liveFields: queryPresentation(query, schema.interfaces),
|
||||
watch: query.declaration.watch,
|
||||
},
|
||||
]),
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,253 +1,259 @@
|
||||
WORKSPACE=1
|
||||
QUERY=2
|
||||
SPECIALIZE=3
|
||||
ROOT=4
|
||||
DOCUMENT=5
|
||||
FRAGMENTS=6
|
||||
VIEW=7
|
||||
MAX=8
|
||||
ALLOW=9
|
||||
POLL=10
|
||||
QUERYABLE=11
|
||||
RPC=12
|
||||
QUERY_REASON=13
|
||||
TYPE=14
|
||||
OBJECT=15
|
||||
STORABLE=16
|
||||
IMPLEMENTS=17
|
||||
REF=18
|
||||
FRAGMENT=19
|
||||
IMPORT=20
|
||||
EXTERNAL=21
|
||||
ATOM=22
|
||||
INTERFACE=23
|
||||
INTERFACES=24
|
||||
PACKAGE=25
|
||||
VALUE=26
|
||||
RELATION=27
|
||||
OPERATION=28
|
||||
FUNCTION=29
|
||||
CONSTRUCTOR=30
|
||||
CONSTRUCTS=31
|
||||
INPUT=32
|
||||
CONFORM=33
|
||||
AS=34
|
||||
BIND=35
|
||||
STATIC=36
|
||||
TO=37
|
||||
PRIVATE=38
|
||||
SHARED=39
|
||||
STATE=40
|
||||
EDGE=41
|
||||
PROJECTION=42
|
||||
WITH=43
|
||||
USING=44
|
||||
VIA=45
|
||||
MATERIALIZE=46
|
||||
IF=47
|
||||
ABSENT=48
|
||||
ON=49
|
||||
POLICY=50
|
||||
DEFAULT=51
|
||||
SOURCE=52
|
||||
REPOSITORY=53
|
||||
COMMIT=54
|
||||
REVISION=55
|
||||
SEMANTIC_MAJOR=56
|
||||
ON_DELETE=57
|
||||
RETAIN_OTHER=58
|
||||
KEYED=59
|
||||
PUBLIC_TRAVERSAL=60
|
||||
ID=61
|
||||
DOC=62
|
||||
MODE=63
|
||||
EMITS=64
|
||||
RECEIVER=65
|
||||
REQUIRES=66
|
||||
ANY=67
|
||||
GET=68
|
||||
SET=69
|
||||
WATCH=70
|
||||
START=71
|
||||
STOP=72
|
||||
READ=73
|
||||
WRITE=74
|
||||
RESOLVE=75
|
||||
CONNECT=76
|
||||
DISCONNECT=77
|
||||
CALL=78
|
||||
WATCH_START=79
|
||||
WATCH_STOP=80
|
||||
SUBSCRIBE=81
|
||||
UNSUBSCRIBE=82
|
||||
OPTIMISTIC_REGISTER=83
|
||||
CRDT=84
|
||||
OPTIONAL_ONE=85
|
||||
EXACTLY_ONE=86
|
||||
MANY_UNIQUE=87
|
||||
MANY=88
|
||||
ORDERED=89
|
||||
UNIT=90
|
||||
WATCH_HANDLE=91
|
||||
MESSAGE=92
|
||||
ATOM_REF=93
|
||||
INTERFACE_REF=94
|
||||
OPTIONAL=95
|
||||
LIST=96
|
||||
RECORD=97
|
||||
BOOL=98
|
||||
BYTES=99
|
||||
DOUBLE=100
|
||||
INT32=101
|
||||
INT64=102
|
||||
STRING=103
|
||||
UINT32=104
|
||||
UINT64=105
|
||||
TRUE=106
|
||||
FALSE=107
|
||||
NULL=108
|
||||
ARROW=109
|
||||
COLON=110
|
||||
SEMI=111
|
||||
COMMA=112
|
||||
DOT=113
|
||||
LBRACE=114
|
||||
RBRACE=115
|
||||
LBRACK=116
|
||||
RBRACK=117
|
||||
LPAREN=118
|
||||
RPAREN=119
|
||||
LT=120
|
||||
GT=121
|
||||
AMP=122
|
||||
EQUAL=123
|
||||
INTEGER=124
|
||||
JSON_NUMBER=125
|
||||
IDENTIFIER=126
|
||||
STRING_LITERAL=127
|
||||
LINE_COMMENT=128
|
||||
BLOCK_COMMENT=129
|
||||
WS=130
|
||||
RESULT_BYTES=2
|
||||
RPC_CALLS=3
|
||||
DEADLINE_MS=4
|
||||
QUERY=5
|
||||
SPECIALIZE=6
|
||||
ROOT=7
|
||||
DOCUMENT=8
|
||||
FRAGMENTS=9
|
||||
VIEW=10
|
||||
MAX=11
|
||||
ALLOW=12
|
||||
POLL=13
|
||||
QUERYABLE=14
|
||||
RPC=15
|
||||
QUERY_REASON=16
|
||||
TYPE=17
|
||||
OBJECT=18
|
||||
STORABLE=19
|
||||
IMPLEMENTS=20
|
||||
REF=21
|
||||
FRAGMENT=22
|
||||
IMPORT=23
|
||||
EXTERNAL=24
|
||||
ATOM=25
|
||||
INTERFACE=26
|
||||
INTERFACES=27
|
||||
PACKAGE=28
|
||||
VALUE=29
|
||||
RELATION=30
|
||||
OPERATION=31
|
||||
FUNCTION=32
|
||||
CONSTRUCTOR=33
|
||||
CONSTRUCTS=34
|
||||
INPUT=35
|
||||
CONFORM=36
|
||||
AS=37
|
||||
BIND=38
|
||||
STATIC=39
|
||||
TO=40
|
||||
PRIVATE=41
|
||||
SHARED=42
|
||||
STATE=43
|
||||
EDGE=44
|
||||
PROJECTION=45
|
||||
WITH=46
|
||||
USING=47
|
||||
VIA=48
|
||||
MATERIALIZE=49
|
||||
IF=50
|
||||
ABSENT=51
|
||||
ON=52
|
||||
POLICY=53
|
||||
DEFAULT=54
|
||||
SOURCE=55
|
||||
REPOSITORY=56
|
||||
COMMIT=57
|
||||
REVISION=58
|
||||
SEMANTIC_MAJOR=59
|
||||
ON_DELETE=60
|
||||
RETAIN_OTHER=61
|
||||
KEYED=62
|
||||
PUBLIC_TRAVERSAL=63
|
||||
ID=64
|
||||
DOC=65
|
||||
MODE=66
|
||||
EMITS=67
|
||||
RECEIVER=68
|
||||
REQUIRES=69
|
||||
ANY=70
|
||||
GET=71
|
||||
SET=72
|
||||
WATCH=73
|
||||
START=74
|
||||
STOP=75
|
||||
READ=76
|
||||
WRITE=77
|
||||
RESOLVE=78
|
||||
CONNECT=79
|
||||
DISCONNECT=80
|
||||
CALL=81
|
||||
WATCH_START=82
|
||||
WATCH_STOP=83
|
||||
SUBSCRIBE=84
|
||||
UNSUBSCRIBE=85
|
||||
OPTIMISTIC_REGISTER=86
|
||||
CRDT=87
|
||||
OPTIONAL_ONE=88
|
||||
EXACTLY_ONE=89
|
||||
MANY_UNIQUE=90
|
||||
MANY=91
|
||||
ORDERED=92
|
||||
UNIT=93
|
||||
WATCH_HANDLE=94
|
||||
MESSAGE=95
|
||||
ATOM_REF=96
|
||||
INTERFACE_REF=97
|
||||
OPTIONAL=98
|
||||
LIST=99
|
||||
RECORD=100
|
||||
BOOL=101
|
||||
BYTES=102
|
||||
DOUBLE=103
|
||||
INT32=104
|
||||
INT64=105
|
||||
STRING=106
|
||||
UINT32=107
|
||||
UINT64=108
|
||||
TRUE=109
|
||||
FALSE=110
|
||||
NULL=111
|
||||
ARROW=112
|
||||
COLON=113
|
||||
SEMI=114
|
||||
COMMA=115
|
||||
DOT=116
|
||||
LBRACE=117
|
||||
RBRACE=118
|
||||
LBRACK=119
|
||||
RBRACK=120
|
||||
LPAREN=121
|
||||
RPAREN=122
|
||||
LT=123
|
||||
GT=124
|
||||
AMP=125
|
||||
EQUAL=126
|
||||
INTEGER=127
|
||||
JSON_NUMBER=128
|
||||
IDENTIFIER=129
|
||||
STRING_LITERAL=130
|
||||
LINE_COMMENT=131
|
||||
BLOCK_COMMENT=132
|
||||
WS=133
|
||||
'workspace'=1
|
||||
'query'=2
|
||||
'specialize'=3
|
||||
'root'=4
|
||||
'document'=5
|
||||
'fragments'=6
|
||||
'view'=7
|
||||
'max'=8
|
||||
'allow'=9
|
||||
'poll'=10
|
||||
'queryable'=11
|
||||
'rpc'=12
|
||||
'query-reason'=13
|
||||
'type'=14
|
||||
'object'=15
|
||||
'storable'=16
|
||||
'implements'=17
|
||||
'ref'=18
|
||||
'fragment'=19
|
||||
'import'=20
|
||||
'external'=21
|
||||
'atom'=22
|
||||
'interface'=23
|
||||
'interfaces'=24
|
||||
'package'=25
|
||||
'value'=26
|
||||
'relation'=27
|
||||
'operation'=28
|
||||
'function'=29
|
||||
'constructor'=30
|
||||
'constructs'=31
|
||||
'input'=32
|
||||
'conform'=33
|
||||
'as'=34
|
||||
'bind'=35
|
||||
'static'=36
|
||||
'to'=37
|
||||
'private'=38
|
||||
'shared'=39
|
||||
'state'=40
|
||||
'edge'=41
|
||||
'projection'=42
|
||||
'with'=43
|
||||
'using'=44
|
||||
'via'=45
|
||||
'materialize'=46
|
||||
'if'=47
|
||||
'absent'=48
|
||||
'on'=49
|
||||
'policy'=50
|
||||
'default'=51
|
||||
'source'=52
|
||||
'repository'=53
|
||||
'commit'=54
|
||||
'revision'=55
|
||||
'semantic-major'=56
|
||||
'on-delete'=57
|
||||
'retain-other'=58
|
||||
'keyed'=59
|
||||
'public-traversal'=60
|
||||
'id'=61
|
||||
'doc'=62
|
||||
'mode'=63
|
||||
'emits'=64
|
||||
'receiver'=65
|
||||
'requires'=66
|
||||
'any'=67
|
||||
'get'=68
|
||||
'set'=69
|
||||
'watch'=70
|
||||
'start'=71
|
||||
'stop'=72
|
||||
'read'=73
|
||||
'write'=74
|
||||
'resolve'=75
|
||||
'connect'=76
|
||||
'disconnect'=77
|
||||
'call'=78
|
||||
'watch-start'=79
|
||||
'watch-stop'=80
|
||||
'subscribe'=81
|
||||
'unsubscribe'=82
|
||||
'optimistic-register'=83
|
||||
'crdt'=84
|
||||
'optional-one'=85
|
||||
'exactly-one'=86
|
||||
'many-unique'=87
|
||||
'many'=88
|
||||
'ordered'=89
|
||||
'unit'=90
|
||||
'watch-handle'=91
|
||||
'message'=92
|
||||
'atom-ref'=93
|
||||
'interface-ref'=94
|
||||
'optional'=95
|
||||
'list'=96
|
||||
'record'=97
|
||||
'bool'=98
|
||||
'bytes'=99
|
||||
'double'=100
|
||||
'int32'=101
|
||||
'int64'=102
|
||||
'string'=103
|
||||
'uint32'=104
|
||||
'uint64'=105
|
||||
'true'=106
|
||||
'false'=107
|
||||
'null'=108
|
||||
'->'=109
|
||||
':'=110
|
||||
';'=111
|
||||
','=112
|
||||
'.'=113
|
||||
'{'=114
|
||||
'}'=115
|
||||
'['=116
|
||||
']'=117
|
||||
'('=118
|
||||
')'=119
|
||||
'<'=120
|
||||
'>'=121
|
||||
'&'=122
|
||||
'='=123
|
||||
'result-bytes'=2
|
||||
'rpc-calls'=3
|
||||
'deadline-ms'=4
|
||||
'query'=5
|
||||
'specialize'=6
|
||||
'root'=7
|
||||
'document'=8
|
||||
'fragments'=9
|
||||
'view'=10
|
||||
'max'=11
|
||||
'allow'=12
|
||||
'poll'=13
|
||||
'queryable'=14
|
||||
'rpc'=15
|
||||
'query-reason'=16
|
||||
'type'=17
|
||||
'object'=18
|
||||
'storable'=19
|
||||
'implements'=20
|
||||
'ref'=21
|
||||
'fragment'=22
|
||||
'import'=23
|
||||
'external'=24
|
||||
'atom'=25
|
||||
'interface'=26
|
||||
'interfaces'=27
|
||||
'package'=28
|
||||
'value'=29
|
||||
'relation'=30
|
||||
'operation'=31
|
||||
'function'=32
|
||||
'constructor'=33
|
||||
'constructs'=34
|
||||
'input'=35
|
||||
'conform'=36
|
||||
'as'=37
|
||||
'bind'=38
|
||||
'static'=39
|
||||
'to'=40
|
||||
'private'=41
|
||||
'shared'=42
|
||||
'state'=43
|
||||
'edge'=44
|
||||
'projection'=45
|
||||
'with'=46
|
||||
'using'=47
|
||||
'via'=48
|
||||
'materialize'=49
|
||||
'if'=50
|
||||
'absent'=51
|
||||
'on'=52
|
||||
'policy'=53
|
||||
'default'=54
|
||||
'source'=55
|
||||
'repository'=56
|
||||
'commit'=57
|
||||
'revision'=58
|
||||
'semantic-major'=59
|
||||
'on-delete'=60
|
||||
'retain-other'=61
|
||||
'keyed'=62
|
||||
'public-traversal'=63
|
||||
'id'=64
|
||||
'doc'=65
|
||||
'mode'=66
|
||||
'emits'=67
|
||||
'receiver'=68
|
||||
'requires'=69
|
||||
'any'=70
|
||||
'get'=71
|
||||
'set'=72
|
||||
'watch'=73
|
||||
'start'=74
|
||||
'stop'=75
|
||||
'read'=76
|
||||
'write'=77
|
||||
'resolve'=78
|
||||
'connect'=79
|
||||
'disconnect'=80
|
||||
'call'=81
|
||||
'watch-start'=82
|
||||
'watch-stop'=83
|
||||
'subscribe'=84
|
||||
'unsubscribe'=85
|
||||
'optimistic-register'=86
|
||||
'crdt'=87
|
||||
'optional-one'=88
|
||||
'exactly-one'=89
|
||||
'many-unique'=90
|
||||
'many'=91
|
||||
'ordered'=92
|
||||
'unit'=93
|
||||
'watch-handle'=94
|
||||
'message'=95
|
||||
'atom-ref'=96
|
||||
'interface-ref'=97
|
||||
'optional'=98
|
||||
'list'=99
|
||||
'record'=100
|
||||
'bool'=101
|
||||
'bytes'=102
|
||||
'double'=103
|
||||
'int32'=104
|
||||
'int64'=105
|
||||
'string'=106
|
||||
'uint32'=107
|
||||
'uint64'=108
|
||||
'true'=109
|
||||
'false'=110
|
||||
'null'=111
|
||||
'->'=112
|
||||
':'=113
|
||||
';'=114
|
||||
','=115
|
||||
'.'=116
|
||||
'{'=117
|
||||
'}'=118
|
||||
'['=119
|
||||
']'=120
|
||||
'('=121
|
||||
')'=122
|
||||
'<'=123
|
||||
'>'=124
|
||||
'&'=125
|
||||
'='=126
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,253 +1,259 @@
|
||||
WORKSPACE=1
|
||||
QUERY=2
|
||||
SPECIALIZE=3
|
||||
ROOT=4
|
||||
DOCUMENT=5
|
||||
FRAGMENTS=6
|
||||
VIEW=7
|
||||
MAX=8
|
||||
ALLOW=9
|
||||
POLL=10
|
||||
QUERYABLE=11
|
||||
RPC=12
|
||||
QUERY_REASON=13
|
||||
TYPE=14
|
||||
OBJECT=15
|
||||
STORABLE=16
|
||||
IMPLEMENTS=17
|
||||
REF=18
|
||||
FRAGMENT=19
|
||||
IMPORT=20
|
||||
EXTERNAL=21
|
||||
ATOM=22
|
||||
INTERFACE=23
|
||||
INTERFACES=24
|
||||
PACKAGE=25
|
||||
VALUE=26
|
||||
RELATION=27
|
||||
OPERATION=28
|
||||
FUNCTION=29
|
||||
CONSTRUCTOR=30
|
||||
CONSTRUCTS=31
|
||||
INPUT=32
|
||||
CONFORM=33
|
||||
AS=34
|
||||
BIND=35
|
||||
STATIC=36
|
||||
TO=37
|
||||
PRIVATE=38
|
||||
SHARED=39
|
||||
STATE=40
|
||||
EDGE=41
|
||||
PROJECTION=42
|
||||
WITH=43
|
||||
USING=44
|
||||
VIA=45
|
||||
MATERIALIZE=46
|
||||
IF=47
|
||||
ABSENT=48
|
||||
ON=49
|
||||
POLICY=50
|
||||
DEFAULT=51
|
||||
SOURCE=52
|
||||
REPOSITORY=53
|
||||
COMMIT=54
|
||||
REVISION=55
|
||||
SEMANTIC_MAJOR=56
|
||||
ON_DELETE=57
|
||||
RETAIN_OTHER=58
|
||||
KEYED=59
|
||||
PUBLIC_TRAVERSAL=60
|
||||
ID=61
|
||||
DOC=62
|
||||
MODE=63
|
||||
EMITS=64
|
||||
RECEIVER=65
|
||||
REQUIRES=66
|
||||
ANY=67
|
||||
GET=68
|
||||
SET=69
|
||||
WATCH=70
|
||||
START=71
|
||||
STOP=72
|
||||
READ=73
|
||||
WRITE=74
|
||||
RESOLVE=75
|
||||
CONNECT=76
|
||||
DISCONNECT=77
|
||||
CALL=78
|
||||
WATCH_START=79
|
||||
WATCH_STOP=80
|
||||
SUBSCRIBE=81
|
||||
UNSUBSCRIBE=82
|
||||
OPTIMISTIC_REGISTER=83
|
||||
CRDT=84
|
||||
OPTIONAL_ONE=85
|
||||
EXACTLY_ONE=86
|
||||
MANY_UNIQUE=87
|
||||
MANY=88
|
||||
ORDERED=89
|
||||
UNIT=90
|
||||
WATCH_HANDLE=91
|
||||
MESSAGE=92
|
||||
ATOM_REF=93
|
||||
INTERFACE_REF=94
|
||||
OPTIONAL=95
|
||||
LIST=96
|
||||
RECORD=97
|
||||
BOOL=98
|
||||
BYTES=99
|
||||
DOUBLE=100
|
||||
INT32=101
|
||||
INT64=102
|
||||
STRING=103
|
||||
UINT32=104
|
||||
UINT64=105
|
||||
TRUE=106
|
||||
FALSE=107
|
||||
NULL=108
|
||||
ARROW=109
|
||||
COLON=110
|
||||
SEMI=111
|
||||
COMMA=112
|
||||
DOT=113
|
||||
LBRACE=114
|
||||
RBRACE=115
|
||||
LBRACK=116
|
||||
RBRACK=117
|
||||
LPAREN=118
|
||||
RPAREN=119
|
||||
LT=120
|
||||
GT=121
|
||||
AMP=122
|
||||
EQUAL=123
|
||||
INTEGER=124
|
||||
JSON_NUMBER=125
|
||||
IDENTIFIER=126
|
||||
STRING_LITERAL=127
|
||||
LINE_COMMENT=128
|
||||
BLOCK_COMMENT=129
|
||||
WS=130
|
||||
RESULT_BYTES=2
|
||||
RPC_CALLS=3
|
||||
DEADLINE_MS=4
|
||||
QUERY=5
|
||||
SPECIALIZE=6
|
||||
ROOT=7
|
||||
DOCUMENT=8
|
||||
FRAGMENTS=9
|
||||
VIEW=10
|
||||
MAX=11
|
||||
ALLOW=12
|
||||
POLL=13
|
||||
QUERYABLE=14
|
||||
RPC=15
|
||||
QUERY_REASON=16
|
||||
TYPE=17
|
||||
OBJECT=18
|
||||
STORABLE=19
|
||||
IMPLEMENTS=20
|
||||
REF=21
|
||||
FRAGMENT=22
|
||||
IMPORT=23
|
||||
EXTERNAL=24
|
||||
ATOM=25
|
||||
INTERFACE=26
|
||||
INTERFACES=27
|
||||
PACKAGE=28
|
||||
VALUE=29
|
||||
RELATION=30
|
||||
OPERATION=31
|
||||
FUNCTION=32
|
||||
CONSTRUCTOR=33
|
||||
CONSTRUCTS=34
|
||||
INPUT=35
|
||||
CONFORM=36
|
||||
AS=37
|
||||
BIND=38
|
||||
STATIC=39
|
||||
TO=40
|
||||
PRIVATE=41
|
||||
SHARED=42
|
||||
STATE=43
|
||||
EDGE=44
|
||||
PROJECTION=45
|
||||
WITH=46
|
||||
USING=47
|
||||
VIA=48
|
||||
MATERIALIZE=49
|
||||
IF=50
|
||||
ABSENT=51
|
||||
ON=52
|
||||
POLICY=53
|
||||
DEFAULT=54
|
||||
SOURCE=55
|
||||
REPOSITORY=56
|
||||
COMMIT=57
|
||||
REVISION=58
|
||||
SEMANTIC_MAJOR=59
|
||||
ON_DELETE=60
|
||||
RETAIN_OTHER=61
|
||||
KEYED=62
|
||||
PUBLIC_TRAVERSAL=63
|
||||
ID=64
|
||||
DOC=65
|
||||
MODE=66
|
||||
EMITS=67
|
||||
RECEIVER=68
|
||||
REQUIRES=69
|
||||
ANY=70
|
||||
GET=71
|
||||
SET=72
|
||||
WATCH=73
|
||||
START=74
|
||||
STOP=75
|
||||
READ=76
|
||||
WRITE=77
|
||||
RESOLVE=78
|
||||
CONNECT=79
|
||||
DISCONNECT=80
|
||||
CALL=81
|
||||
WATCH_START=82
|
||||
WATCH_STOP=83
|
||||
SUBSCRIBE=84
|
||||
UNSUBSCRIBE=85
|
||||
OPTIMISTIC_REGISTER=86
|
||||
CRDT=87
|
||||
OPTIONAL_ONE=88
|
||||
EXACTLY_ONE=89
|
||||
MANY_UNIQUE=90
|
||||
MANY=91
|
||||
ORDERED=92
|
||||
UNIT=93
|
||||
WATCH_HANDLE=94
|
||||
MESSAGE=95
|
||||
ATOM_REF=96
|
||||
INTERFACE_REF=97
|
||||
OPTIONAL=98
|
||||
LIST=99
|
||||
RECORD=100
|
||||
BOOL=101
|
||||
BYTES=102
|
||||
DOUBLE=103
|
||||
INT32=104
|
||||
INT64=105
|
||||
STRING=106
|
||||
UINT32=107
|
||||
UINT64=108
|
||||
TRUE=109
|
||||
FALSE=110
|
||||
NULL=111
|
||||
ARROW=112
|
||||
COLON=113
|
||||
SEMI=114
|
||||
COMMA=115
|
||||
DOT=116
|
||||
LBRACE=117
|
||||
RBRACE=118
|
||||
LBRACK=119
|
||||
RBRACK=120
|
||||
LPAREN=121
|
||||
RPAREN=122
|
||||
LT=123
|
||||
GT=124
|
||||
AMP=125
|
||||
EQUAL=126
|
||||
INTEGER=127
|
||||
JSON_NUMBER=128
|
||||
IDENTIFIER=129
|
||||
STRING_LITERAL=130
|
||||
LINE_COMMENT=131
|
||||
BLOCK_COMMENT=132
|
||||
WS=133
|
||||
'workspace'=1
|
||||
'query'=2
|
||||
'specialize'=3
|
||||
'root'=4
|
||||
'document'=5
|
||||
'fragments'=6
|
||||
'view'=7
|
||||
'max'=8
|
||||
'allow'=9
|
||||
'poll'=10
|
||||
'queryable'=11
|
||||
'rpc'=12
|
||||
'query-reason'=13
|
||||
'type'=14
|
||||
'object'=15
|
||||
'storable'=16
|
||||
'implements'=17
|
||||
'ref'=18
|
||||
'fragment'=19
|
||||
'import'=20
|
||||
'external'=21
|
||||
'atom'=22
|
||||
'interface'=23
|
||||
'interfaces'=24
|
||||
'package'=25
|
||||
'value'=26
|
||||
'relation'=27
|
||||
'operation'=28
|
||||
'function'=29
|
||||
'constructor'=30
|
||||
'constructs'=31
|
||||
'input'=32
|
||||
'conform'=33
|
||||
'as'=34
|
||||
'bind'=35
|
||||
'static'=36
|
||||
'to'=37
|
||||
'private'=38
|
||||
'shared'=39
|
||||
'state'=40
|
||||
'edge'=41
|
||||
'projection'=42
|
||||
'with'=43
|
||||
'using'=44
|
||||
'via'=45
|
||||
'materialize'=46
|
||||
'if'=47
|
||||
'absent'=48
|
||||
'on'=49
|
||||
'policy'=50
|
||||
'default'=51
|
||||
'source'=52
|
||||
'repository'=53
|
||||
'commit'=54
|
||||
'revision'=55
|
||||
'semantic-major'=56
|
||||
'on-delete'=57
|
||||
'retain-other'=58
|
||||
'keyed'=59
|
||||
'public-traversal'=60
|
||||
'id'=61
|
||||
'doc'=62
|
||||
'mode'=63
|
||||
'emits'=64
|
||||
'receiver'=65
|
||||
'requires'=66
|
||||
'any'=67
|
||||
'get'=68
|
||||
'set'=69
|
||||
'watch'=70
|
||||
'start'=71
|
||||
'stop'=72
|
||||
'read'=73
|
||||
'write'=74
|
||||
'resolve'=75
|
||||
'connect'=76
|
||||
'disconnect'=77
|
||||
'call'=78
|
||||
'watch-start'=79
|
||||
'watch-stop'=80
|
||||
'subscribe'=81
|
||||
'unsubscribe'=82
|
||||
'optimistic-register'=83
|
||||
'crdt'=84
|
||||
'optional-one'=85
|
||||
'exactly-one'=86
|
||||
'many-unique'=87
|
||||
'many'=88
|
||||
'ordered'=89
|
||||
'unit'=90
|
||||
'watch-handle'=91
|
||||
'message'=92
|
||||
'atom-ref'=93
|
||||
'interface-ref'=94
|
||||
'optional'=95
|
||||
'list'=96
|
||||
'record'=97
|
||||
'bool'=98
|
||||
'bytes'=99
|
||||
'double'=100
|
||||
'int32'=101
|
||||
'int64'=102
|
||||
'string'=103
|
||||
'uint32'=104
|
||||
'uint64'=105
|
||||
'true'=106
|
||||
'false'=107
|
||||
'null'=108
|
||||
'->'=109
|
||||
':'=110
|
||||
';'=111
|
||||
','=112
|
||||
'.'=113
|
||||
'{'=114
|
||||
'}'=115
|
||||
'['=116
|
||||
']'=117
|
||||
'('=118
|
||||
')'=119
|
||||
'<'=120
|
||||
'>'=121
|
||||
'&'=122
|
||||
'='=123
|
||||
'result-bytes'=2
|
||||
'rpc-calls'=3
|
||||
'deadline-ms'=4
|
||||
'query'=5
|
||||
'specialize'=6
|
||||
'root'=7
|
||||
'document'=8
|
||||
'fragments'=9
|
||||
'view'=10
|
||||
'max'=11
|
||||
'allow'=12
|
||||
'poll'=13
|
||||
'queryable'=14
|
||||
'rpc'=15
|
||||
'query-reason'=16
|
||||
'type'=17
|
||||
'object'=18
|
||||
'storable'=19
|
||||
'implements'=20
|
||||
'ref'=21
|
||||
'fragment'=22
|
||||
'import'=23
|
||||
'external'=24
|
||||
'atom'=25
|
||||
'interface'=26
|
||||
'interfaces'=27
|
||||
'package'=28
|
||||
'value'=29
|
||||
'relation'=30
|
||||
'operation'=31
|
||||
'function'=32
|
||||
'constructor'=33
|
||||
'constructs'=34
|
||||
'input'=35
|
||||
'conform'=36
|
||||
'as'=37
|
||||
'bind'=38
|
||||
'static'=39
|
||||
'to'=40
|
||||
'private'=41
|
||||
'shared'=42
|
||||
'state'=43
|
||||
'edge'=44
|
||||
'projection'=45
|
||||
'with'=46
|
||||
'using'=47
|
||||
'via'=48
|
||||
'materialize'=49
|
||||
'if'=50
|
||||
'absent'=51
|
||||
'on'=52
|
||||
'policy'=53
|
||||
'default'=54
|
||||
'source'=55
|
||||
'repository'=56
|
||||
'commit'=57
|
||||
'revision'=58
|
||||
'semantic-major'=59
|
||||
'on-delete'=60
|
||||
'retain-other'=61
|
||||
'keyed'=62
|
||||
'public-traversal'=63
|
||||
'id'=64
|
||||
'doc'=65
|
||||
'mode'=66
|
||||
'emits'=67
|
||||
'receiver'=68
|
||||
'requires'=69
|
||||
'any'=70
|
||||
'get'=71
|
||||
'set'=72
|
||||
'watch'=73
|
||||
'start'=74
|
||||
'stop'=75
|
||||
'read'=76
|
||||
'write'=77
|
||||
'resolve'=78
|
||||
'connect'=79
|
||||
'disconnect'=80
|
||||
'call'=81
|
||||
'watch-start'=82
|
||||
'watch-stop'=83
|
||||
'subscribe'=84
|
||||
'unsubscribe'=85
|
||||
'optimistic-register'=86
|
||||
'crdt'=87
|
||||
'optional-one'=88
|
||||
'exactly-one'=89
|
||||
'many-unique'=90
|
||||
'many'=91
|
||||
'ordered'=92
|
||||
'unit'=93
|
||||
'watch-handle'=94
|
||||
'message'=95
|
||||
'atom-ref'=96
|
||||
'interface-ref'=97
|
||||
'optional'=98
|
||||
'list'=99
|
||||
'record'=100
|
||||
'bool'=101
|
||||
'bytes'=102
|
||||
'double'=103
|
||||
'int32'=104
|
||||
'int64'=105
|
||||
'string'=106
|
||||
'uint32'=107
|
||||
'uint64'=108
|
||||
'true'=109
|
||||
'false'=110
|
||||
'null'=111
|
||||
'->'=112
|
||||
':'=113
|
||||
';'=114
|
||||
','=115
|
||||
'.'=116
|
||||
'{'=117
|
||||
'}'=118
|
||||
'['=119
|
||||
']'=120
|
||||
'('=121
|
||||
')'=122
|
||||
'<'=123
|
||||
'>'=124
|
||||
'&'=125
|
||||
'='=126
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+155
-46
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+36
-58
File diff suppressed because one or more lines are too long
@@ -2,15 +2,15 @@
|
||||
// @generated from file quixos/refs.proto (package quixos, syntax proto3)
|
||||
/* eslint-disable */
|
||||
|
||||
import type { GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
||||
import { fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
||||
import type { GenEnum, GenFile, GenMessage } from "@bufbuild/protobuf/codegenv2";
|
||||
import { enumDesc, fileDesc, messageDesc } from "@bufbuild/protobuf/codegenv2";
|
||||
import type { Message } from "@bufbuild/protobuf";
|
||||
|
||||
/**
|
||||
* Describes the file quixos/refs.proto.
|
||||
*/
|
||||
export const file_quixos_refs: GenFile = /*@__PURE__*/
|
||||
fileDesc("ChFxdWl4b3MvcmVmcy5wcm90bxIGcXVpeG9zInUKDUNhcGFiaWxpdHlSZWYSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAEgASgJEhQKDG9wZXJhdGlvbl9pZBgCIAEoCRIvCgtjb25mb3JtYW5jZRgDIAEoCzIaLnF1aXhvcy5Db25mb3JtYW5jZVdpdG5lc3MilgEKEkNvbmZvcm1hbmNlV2l0bmVzcxIRCglvYmplY3RfaWQYASABKAkSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAIgASgJEhYKDmNvbmZvcm1hbmNlX2lkGAMgASgJEh0KFXdvcmtzcGFjZV9yZXZpc2lvbl9pZBgEIAEoCRIXCg93b3Jrc3BhY2VfZXBvY2gYBSABKAkiQgoQUGFja2FnZUV4cG9ydFJlZhIbChNwYWNrYWdlX3JldmlzaW9uX2lkGAEgASgJEhEKCWV4cG9ydF9pZBgCIAEoCSLYAQoSSW5qZWN0ZWREZXBlbmRlbmN5Eg8KB3BvcnRfaWQYASABKAkSFwoNc3RhdGVfc2xvdF9pZBgCIAEoCUgAEiYKBGVkZ2UYAyABKAsyFi5xdWl4b3MuRWRnZURlcGVuZGVuY3lIABIfChVpbnRlcmZhY2VfcmV2aXNpb25faWQYBCABKAlIABIdChNjb25zdHJ1Y3Rvcl9hdG9tX2lkGAUgASgJSAASEgoIcXVlcnlfaWQYByABKAlIABIRCglvYmplY3RfaWQYBiABKAlCCQoHYmluZGluZyI9Cg5FZGdlRGVwZW5kZW5jeRIUCgxlZGdlX3R5cGVfaWQYASABKAkSFQoNcHJvamVjdGlvbl9pZBgCIAEoCWIGcHJvdG8z");
|
||||
fileDesc("ChFxdWl4b3MvcmVmcy5wcm90bxIGcXVpeG9zInUKDUNhcGFiaWxpdHlSZWYSHQoVaW50ZXJmYWNlX3JldmlzaW9uX2lkGAEgASgJEhQKDG9wZXJhdGlvbl9pZBgCIAEoCRIvCgtjb25mb3JtYW5jZRgDIAEoCzIaLnF1aXhvcy5Db25mb3JtYW5jZVdpdG5lc3Mi0QEKDEZpZWxkRWRpdGluZxIbChNnZXR0ZXJfb3BlcmF0aW9uX2lkGAEgASgJEhsKE3NldHRlcl9vcGVyYXRpb25faWQYAiABKAkSFQoNZG9jdW1lbnRfdHlwZRgDIAEoCRIWCg5iaW5kaW5nX2RpZ2VzdBgEIAEoCRInCgRtb2RlGAUgASgOMhkucXVpeG9zLkZpZWxkRWRpdGluZy5Nb2RlIi8KBE1vZGUSDwoLVU5TUEVDSUZJRUQQABIMCghSRUdJU1RFUhABEggKBENSRFQQAiKWAQoSQ29uZm9ybWFuY2VXaXRuZXNzEhEKCW9iamVjdF9pZBgBIAEoCRIdChVpbnRlcmZhY2VfcmV2aXNpb25faWQYAiABKAkSFgoOY29uZm9ybWFuY2VfaWQYAyABKAkSHQoVd29ya3NwYWNlX3JldmlzaW9uX2lkGAQgASgJEhcKD3dvcmtzcGFjZV9lcG9jaBgFIAEoCSJCChBQYWNrYWdlRXhwb3J0UmVmEhsKE3BhY2thZ2VfcmV2aXNpb25faWQYASABKAkSEQoJZXhwb3J0X2lkGAIgASgJItgBChJJbmplY3RlZERlcGVuZGVuY3kSDwoHcG9ydF9pZBgBIAEoCRIXCg1zdGF0ZV9zbG90X2lkGAIgASgJSAASJgoEZWRnZRgDIAEoCzIWLnF1aXhvcy5FZGdlRGVwZW5kZW5jeUgAEh8KFWludGVyZmFjZV9yZXZpc2lvbl9pZBgEIAEoCUgAEh0KE2NvbnN0cnVjdG9yX2F0b21faWQYBSABKAlIABISCghxdWVyeV9pZBgHIAEoCUgAEhEKCW9iamVjdF9pZBgGIAEoCUIJCgdiaW5kaW5nIj0KDkVkZ2VEZXBlbmRlbmN5EhQKDGVkZ2VfdHlwZV9pZBgBIAEoCRIVCg1wcm9qZWN0aW9uX2lkGAIgASgJYgZwcm90bzM");
|
||||
|
||||
/**
|
||||
* @generated from message quixos.CapabilityRef
|
||||
@@ -41,6 +41,71 @@ export type CapabilityRef = Message<"quixos.CapabilityRef"> & {
|
||||
export const CapabilityRefSchema: GenMessage<CapabilityRef> = /*@__PURE__*/
|
||||
messageDesc(file_quixos_refs, 0);
|
||||
|
||||
/**
|
||||
* Resolved native editing semantics. A source snapshot alone grants no writer.
|
||||
*
|
||||
* @generated from message quixos.FieldEditing
|
||||
*/
|
||||
export type FieldEditing = Message<"quixos.FieldEditing"> & {
|
||||
/**
|
||||
* @generated from field: string getter_operation_id = 1;
|
||||
*/
|
||||
getterOperationId: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string setter_operation_id = 2;
|
||||
*/
|
||||
setterOperationId: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string document_type = 3;
|
||||
*/
|
||||
documentType: string;
|
||||
|
||||
/**
|
||||
* @generated from field: string binding_digest = 4;
|
||||
*/
|
||||
bindingDigest: string;
|
||||
|
||||
/**
|
||||
* @generated from field: quixos.FieldEditing.Mode mode = 5;
|
||||
*/
|
||||
mode: FieldEditing_Mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Describes the message quixos.FieldEditing.
|
||||
* Use `create(FieldEditingSchema)` to create a new message.
|
||||
*/
|
||||
export const FieldEditingSchema: GenMessage<FieldEditing> = /*@__PURE__*/
|
||||
messageDesc(file_quixos_refs, 1);
|
||||
|
||||
/**
|
||||
* @generated from enum quixos.FieldEditing.Mode
|
||||
*/
|
||||
export enum FieldEditing_Mode {
|
||||
/**
|
||||
* @generated from enum value: UNSPECIFIED = 0;
|
||||
*/
|
||||
UNSPECIFIED = 0,
|
||||
|
||||
/**
|
||||
* @generated from enum value: REGISTER = 1;
|
||||
*/
|
||||
REGISTER = 1,
|
||||
|
||||
/**
|
||||
* @generated from enum value: CRDT = 2;
|
||||
*/
|
||||
CRDT = 2,
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes the enum quixos.FieldEditing.Mode.
|
||||
*/
|
||||
export const FieldEditing_ModeSchema: GenEnum<FieldEditing_Mode> = /*@__PURE__*/
|
||||
enumDesc(file_quixos_refs, 1, 0);
|
||||
|
||||
/**
|
||||
* @generated from message quixos.ConformanceWitness
|
||||
*/
|
||||
@@ -76,7 +141,7 @@ export type ConformanceWitness = Message<"quixos.ConformanceWitness"> & {
|
||||
* Use `create(ConformanceWitnessSchema)` to create a new message.
|
||||
*/
|
||||
export const ConformanceWitnessSchema: GenMessage<ConformanceWitness> = /*@__PURE__*/
|
||||
messageDesc(file_quixos_refs, 1);
|
||||
messageDesc(file_quixos_refs, 2);
|
||||
|
||||
/**
|
||||
* @generated from message quixos.PackageExportRef
|
||||
@@ -98,7 +163,7 @@ export type PackageExportRef = Message<"quixos.PackageExportRef"> & {
|
||||
* Use `create(PackageExportRefSchema)` to create a new message.
|
||||
*/
|
||||
export const PackageExportRefSchema: GenMessage<PackageExportRef> = /*@__PURE__*/
|
||||
messageDesc(file_quixos_refs, 2);
|
||||
messageDesc(file_quixos_refs, 3);
|
||||
|
||||
/**
|
||||
* @generated from message quixos.InjectedDependency
|
||||
@@ -158,7 +223,7 @@ export type InjectedDependency = Message<"quixos.InjectedDependency"> & {
|
||||
* Use `create(InjectedDependencySchema)` to create a new message.
|
||||
*/
|
||||
export const InjectedDependencySchema: GenMessage<InjectedDependency> = /*@__PURE__*/
|
||||
messageDesc(file_quixos_refs, 3);
|
||||
messageDesc(file_quixos_refs, 4);
|
||||
|
||||
/**
|
||||
* @generated from message quixos.EdgeDependency
|
||||
@@ -180,5 +245,5 @@ export type EdgeDependency = Message<"quixos.EdgeDependency"> & {
|
||||
* Use `create(EdgeDependencySchema)` to create a new message.
|
||||
*/
|
||||
export const EdgeDependencySchema: GenMessage<EdgeDependency> = /*@__PURE__*/
|
||||
messageDesc(file_quixos_refs, 4);
|
||||
messageDesc(file_quixos_refs, 5);
|
||||
|
||||
|
||||
+37
-4
@@ -101,7 +101,7 @@ export async function compileQuery(
|
||||
if (node.name.value.startsWith("__")) fail("QUERY_UNSUPPORTED_FEATURE", "Introspection is not supported", node);
|
||||
},
|
||||
Directive(node) {
|
||||
if (!["include", "skip"].includes(node.name.value))
|
||||
if (!["include", "skip", "live"].includes(node.name.value))
|
||||
fail("QUERY_UNSUPPORTED_FEATURE", `Unsupported directive ${node.name.value}`, node);
|
||||
},
|
||||
InlineFragment(node) {
|
||||
@@ -180,6 +180,15 @@ export async function compileQuery(
|
||||
Field(node) {
|
||||
const parent = info.getParentType();
|
||||
const contract = parent && generated.byName.get(parent.name);
|
||||
if (node.directives?.some((directive) => directive.name.value === "live")) {
|
||||
const member = contract?.members.find((entry) => entry.displayName === node.name.value);
|
||||
if (!member || member.kind !== "value" || member.queryRead?.execution !== "native")
|
||||
fail(
|
||||
"QUERY_LIVE_UNSUPPORTED",
|
||||
"@live requires a direct native-queryable value field, not RPC enrichment or a synthetic result",
|
||||
node,
|
||||
);
|
||||
}
|
||||
if (!contract || node.name.value === "_qx") return;
|
||||
mark(contract.revisionId, node.name.value, "select", node);
|
||||
const member = contract.members.find((entry) => entry.displayName === node.name.value)!;
|
||||
@@ -286,9 +295,12 @@ export async function compileQuery(
|
||||
field.type,
|
||||
selection.selectionSet,
|
||||
depth + 1,
|
||||
conditional || !!selection.directives?.length,
|
||||
conditional || !!selection.directives?.some((entry) => entry.name.value !== "live"),
|
||||
);
|
||||
if ((conditional || selection.directives?.length) && fields[key]!.kind !== "optional")
|
||||
if (
|
||||
(conditional || selection.directives?.some((entry) => entry.name.value !== "live")) &&
|
||||
fields[key]!.kind !== "optional"
|
||||
)
|
||||
fields[key] = valueType.optional(fields[key]!);
|
||||
if (previous) fields[key] = mergeOutput(previous, fields[key]!);
|
||||
}
|
||||
@@ -354,7 +366,9 @@ export async function compileQuery(
|
||||
}
|
||||
};
|
||||
const conditions = (directives: readonly DirectiveNode[] = []) =>
|
||||
directives.map((directive) => ({
|
||||
directives
|
||||
.filter((directive) => directive.name.value !== "live")
|
||||
.map((directive) => ({
|
||||
include: directive.name.value === "include",
|
||||
value: argument(directive.arguments!.find((entry) => entry.name.value === "if")!.value),
|
||||
}));
|
||||
@@ -390,6 +404,13 @@ export async function compileQuery(
|
||||
{
|
||||
name: node.name.value,
|
||||
key: node.alias?.value ?? node.name.value,
|
||||
...(node.directives?.some((directive) => directive.name.value === "live")
|
||||
? {
|
||||
liveSelectionId: createHash("sha256")
|
||||
.update(JSON.stringify([node.loc?.source.name, node.loc?.start, contract?.revisionId, member?.id]))
|
||||
.digest("hex"),
|
||||
}
|
||||
: {}),
|
||||
...(member && contract ? { interfaceRevisionId: contract.revisionId, memberId: member.id } : {}),
|
||||
...(member?.kind === "relationship" ? { targetInterfaceRevisionId: generated.target(member) } : {}),
|
||||
conditions: [...inherited, ...conditions(node.directives)],
|
||||
@@ -405,6 +426,18 @@ export async function compileQuery(
|
||||
const normalized = print(document),
|
||||
schema = printSchema(generated.schema);
|
||||
const selections = selection(operations[0]!.selectionSet, generated.schema.getQueryType()!);
|
||||
const checkPresentation = (entries: QuerySelection[]) => {
|
||||
for (const key of new Set(entries.map((entry) => entry.key))) {
|
||||
const siblings = entries.filter((entry) => entry.key === key);
|
||||
if (siblings.some((entry) => entry.liveSelectionId) && siblings.some((entry) => !entry.liveSelectionId))
|
||||
throw new QueryCompileError(
|
||||
"QUERY_LIVE_CONFLICT",
|
||||
`${key} mixes live and plain selections; use separate aliases`,
|
||||
);
|
||||
checkPresentation(siblings.flatMap((entry) => entry.selection));
|
||||
}
|
||||
};
|
||||
checkPresentation(selections);
|
||||
const definitionDigest = createHash("sha256")
|
||||
.update(
|
||||
canonicalJson({
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import type { InterfaceRevision, ValueType } from "../capability-model/types.js";
|
||||
import type { CheckedQuery, QuerySelection } from "./types.js";
|
||||
|
||||
/** Browser presentation is separate from the portable query value contract. */
|
||||
export function queryPresentation(query: CheckedQuery, interfaces: readonly InterfaceRevision[]) {
|
||||
const result: {
|
||||
path: string[];
|
||||
selectionId: string;
|
||||
interfaceRevisionId: string;
|
||||
getOperationId: string;
|
||||
setOperationId?: string;
|
||||
watchOperationId?: string;
|
||||
inputKind: "value" | "fields";
|
||||
valueType: ValueType;
|
||||
conditions: (QuerySelection["conditions"][number] & { defaultValue?: boolean })[];
|
||||
}[] = [];
|
||||
const visit = (type: ValueType, selections: QuerySelection[], path: string[]) => {
|
||||
if (type.kind === "optional") return visit(type.value, selections, path);
|
||||
if (type.kind === "list") return visit(type.value, selections, [...path, "*"]);
|
||||
if (type.kind !== "record") return;
|
||||
for (const [name, field] of Object.entries(type.fields)) {
|
||||
const matches = selections.filter((entry) => entry.key === name);
|
||||
if (matches.some((entry) => entry.liveSelectionId) && matches.some((entry) => !entry.liveSelectionId))
|
||||
throw new Error(`QUERY_LIVE_CONFLICT: ${[...path, name].join(".")} mixes live and plain selections`);
|
||||
for (const entry of matches) {
|
||||
if (entry.liveSelectionId) {
|
||||
const iface = interfaces.find((iface) => iface.revisionId === entry.interfaceRevisionId)!;
|
||||
const member = iface.members.find((member) => member.id === entry.memberId)!;
|
||||
if (member.kind !== "value") throw new Error("QUERY_LIVE_UNSUPPORTED");
|
||||
const get = member.operations.find((op) => op.displayName === "get")!;
|
||||
const set = member.operations.find((op) => op.displayName === "set");
|
||||
result.push({
|
||||
path: [...path, name],
|
||||
selectionId: entry.liveSelectionId,
|
||||
interfaceRevisionId: iface.revisionId,
|
||||
getOperationId: get.id,
|
||||
setOperationId: set?.id,
|
||||
watchOperationId: member.operations.find((op) => op.displayName === "watch-start")?.id,
|
||||
inputKind: set?.inputType.kind === "record" ? "fields" : "value",
|
||||
valueType: get.outputType,
|
||||
conditions: entry.conditions.map((condition) => {
|
||||
const fallback =
|
||||
condition.value.kind === "variable" ? query.variableDefaults[condition.value.name] : undefined;
|
||||
return {
|
||||
...condition,
|
||||
...(fallback?.kind === "literal" && typeof fallback.value === "boolean"
|
||||
? { defaultValue: fallback.value }
|
||||
: {}),
|
||||
};
|
||||
}),
|
||||
});
|
||||
} else visit(field, entry.selection, [...path, name]);
|
||||
}
|
||||
}
|
||||
};
|
||||
visit(query.output, query.selection, []);
|
||||
return result;
|
||||
}
|
||||
@@ -10,6 +10,9 @@ import {
|
||||
GraphQLList,
|
||||
GraphQLNonNull,
|
||||
GraphQLSchema,
|
||||
GraphQLDirective,
|
||||
DirectiveLocation,
|
||||
specifiedDirectives,
|
||||
type GraphQLOutputType,
|
||||
type GraphQLInputType,
|
||||
type GraphQLFieldConfigMap,
|
||||
@@ -241,6 +244,7 @@ export function querySchema(
|
||||
return result;
|
||||
};
|
||||
const schema = new GraphQLSchema({
|
||||
directives: [...specifiedDirectives, new GraphQLDirective({ name: "live", locations: [DirectiveLocation.FIELD] })],
|
||||
query: new GraphQLObjectType({
|
||||
name: "QxQuery",
|
||||
fields: { root: { type: new GraphQLNonNull(object(declaration.root)) } },
|
||||
|
||||
@@ -98,6 +98,7 @@ export type QueryArgument =
|
||||
| { kind: "list"; values: QueryArgument[] }
|
||||
| { kind: "object"; fields: Record<string, QueryArgument> };
|
||||
export interface QuerySelection {
|
||||
liveSelectionId?: string;
|
||||
name: string;
|
||||
key: string;
|
||||
interfaceRevisionId?: InterfaceRevisionId;
|
||||
|
||||
Vendored
+3
@@ -42,6 +42,9 @@ const pkg = resource(`import interface Tasks; import interface Task;
|
||||
package Reports id "reports" revision "reports@1" {
|
||||
query Report id "report" root Tasks document "report.graphql" operation "Report" {
|
||||
max rows 50;
|
||||
max result-bytes 1048576;
|
||||
max rpc-calls 100;
|
||||
max deadline-ms 10000;
|
||||
view TaskObject as Task;
|
||||
allow Task.score aggregate "Bounded aggregation fixture";
|
||||
allow Task.score predicate "Bounded aggregation fixture";
|
||||
|
||||
Vendored
+13
-4
@@ -8,7 +8,7 @@ export const queryFixtureSource = {
|
||||
repository: "https://query-fixture.example.test/source.git",
|
||||
commit: "1".repeat(40),
|
||||
};
|
||||
export async function queryWorkspaceFixture() {
|
||||
export async function queryWorkspaceFixture(options: { live?: boolean } = {}) {
|
||||
const interfaces = new Map<string, InterfaceRevision>();
|
||||
const sources: Record<string, string> = {};
|
||||
function iface(name: string, members: string, parameters = "") {
|
||||
@@ -29,7 +29,7 @@ export async function queryWorkspaceFixture() {
|
||||
`
|
||||
queryable value title id "title" : string {get id "title:get"; set id "title:set";}
|
||||
queryable value done id "done" : bool {get id "done:get";}
|
||||
queryable value rank id "rank" : int64 {get id "rank:get";}
|
||||
queryable value rank id "rank" : int64 {get id "rank:get"; set id "rank:set";}
|
||||
queryable relation assignee id "assignee" : optional-one interface PersonFacts {resolve id "assignee:resolve";}
|
||||
queryable rpc value score id "score" : int32 {get id "score:get";}
|
||||
`,
|
||||
@@ -81,7 +81,16 @@ export async function queryWorkspaceFixture() {
|
||||
"score-totals.graphql": `query ScoreTotals {root {_qx {relations {items {aggregate {count sum {score}}}}}}}`,
|
||||
};
|
||||
pkg.checkedQueries = await Promise.all(
|
||||
pkg.queries!.map((query) => compileQuery(query, allInterfaces, async (name) => documents[name]!)),
|
||||
pkg.queries!.map((query) =>
|
||||
compileQuery(query, allInterfaces, async (name) =>
|
||||
options.live
|
||||
? documents[name]!.replace(/\btitle\b/g, "title @live").replace(
|
||||
"title @live rank done",
|
||||
"title @live rank @live done @live",
|
||||
)
|
||||
: documents[name]!,
|
||||
),
|
||||
),
|
||||
);
|
||||
const implementation = (atom: string) => `conform ${atom} as TaskFacts id "${atom}-facts" {
|
||||
private state Title${atom} id "${atom}:title" on ${atom} : string policy crdt(string) default "Untitled";
|
||||
@@ -92,7 +101,7 @@ export async function queryWorkspaceFixture() {
|
||||
interface PersonFacts projection tasks id "${atom}:assignee:inverse" many;
|
||||
}
|
||||
bind title.get to state Title${atom}.read;
|
||||
bind title.set to package Queries.titleSet with {title to state Title${atom};};
|
||||
${options.live ? `bind title.set to state Title${atom}.write;` : `bind title.set to package Queries.titleSet with {title to state Title${atom};};`}
|
||||
bind done to state Done${atom}; bind rank to state Rank${atom};
|
||||
bind assignee.resolve to edge Assignee${atom}.assignee.resolve;
|
||||
bind score.get to package Queries.score query-reason "Explicit bounded score computation";
|
||||
|
||||
@@ -4,6 +4,8 @@ import { compileCapabilityResourceSource } from "../src/capability-language/inde
|
||||
import { compileQuery } from "../src/query/compile.js";
|
||||
import { QueryCompileError } from "../src/query/types.js";
|
||||
import { checkQueryTemplate } from "../src/query/templates.js";
|
||||
import { queryPresentation } from "../src/query/presentation.js";
|
||||
import { querySelectionToWire } from "../src/query/proto.js";
|
||||
import type { InterfaceRevision } from "../src/capability-model/types.js";
|
||||
|
||||
const source = { repository: "https://example.test/queries.git", commit: "a".repeat(40) };
|
||||
@@ -125,6 +127,48 @@ const document = `query Upcoming($first: Int!, $before: Int64!) {
|
||||
const compile = (query = document, row = "fragment Row on TaskFacts { title due }", clauses = "") =>
|
||||
compileQuery(fixture(clauses), [collection, facts], async (name) => (name.endsWith("row.graphql") ? row : query));
|
||||
|
||||
test("live selections preserve aliases, nullable values, fragment conditions and wire identity", async () => {
|
||||
const checked = await compile(
|
||||
`query Upcoming($show: Boolean!) {root {items(first: 3) {entries {node {plain: title ...Row @include(if: $show)}}}}}`,
|
||||
`fragment Row on TaskFacts {label: title @live due @live}`,
|
||||
);
|
||||
const fields = queryPresentation(checked, [collection, facts]);
|
||||
assert.deepEqual(
|
||||
fields.map((f) => f.path),
|
||||
[
|
||||
["root", "items", "entries", "*", "node", "label"],
|
||||
["root", "items", "entries", "*", "node", "due"],
|
||||
],
|
||||
);
|
||||
assert.equal(fields[0]!.getOperationId, "title:get");
|
||||
assert.equal(fields[0]!.setOperationId, undefined);
|
||||
assert.equal(fields[1]!.valueType.kind, "optional");
|
||||
assert.equal(fields[0]!.conditions.length, 1);
|
||||
assert.ok(JSON.stringify(checked.selection.map(querySelectionToWire)).includes(fields[0]!.selectionId));
|
||||
const defaults = await compile(
|
||||
`query Upcoming($show: Boolean! = true) {root {items(first: 3) {entries {node {...Row @include(if: $show)}}}}}`,
|
||||
"fragment Row on TaskFacts {title @live}",
|
||||
);
|
||||
assert.equal(queryPresentation(defaults, [collection, facts])[0]!.conditions[0]!.defaultValue, true);
|
||||
});
|
||||
|
||||
test("live selections reject RPC getters, synthetic selections and conflicting presentations", async () => {
|
||||
for (const [selected, code] of [
|
||||
["score @live", "QUERY_LIVE_UNSUPPORTED"],
|
||||
["_qx @live {ref}", "QUERY_LIVE_UNSUPPORTED"],
|
||||
["title @live title", "QUERY_LIVE_CONFLICT"],
|
||||
["title @live(unchecked: true)", "QUERY_VALIDATION"],
|
||||
])
|
||||
await assert.rejects(
|
||||
compile(
|
||||
`query Upcoming {root {items(first: 3) {entries {node {...Row}}}}}`,
|
||||
`fragment Row on TaskFacts {${selected}}`,
|
||||
'allow TaskFacts.score select "bounded";',
|
||||
),
|
||||
(error: unknown) => error instanceof QueryCompileError && error.code === code,
|
||||
);
|
||||
});
|
||||
|
||||
test("query dependency ports resolve exact exports without declaration ordering constraints", () => {
|
||||
const result = compileCapabilityResourceSource(
|
||||
`import interface Tasks;
|
||||
|
||||
+26
-10
@@ -7,13 +7,14 @@ import { spawnSync } from "node:child_process";
|
||||
import { compileCapabilityResourceSource, compileCapabilitySource } from "../src/capability-language/parser.js";
|
||||
import { generateReactBindings } from "../src/bindings/react.js";
|
||||
import { reactPlatformTypes } from "../src/bindings/react-platform.js";
|
||||
import { compileQuery } from "../src/query/compile.js";
|
||||
|
||||
const source = { repository: "https://example.test/fields.git", commit: "a".repeat(40) };
|
||||
test("React bindings preserve read-only, writable and nested reference contracts", async (t) => {
|
||||
const iface = compileCapabilityResourceSource(
|
||||
`interface Fields id "fields" revision "fields@1" {
|
||||
value title id "title" : string { get id "title:get"; set id "title:set"; watch start id "watch" stop id "stop"; }
|
||||
value summary id "summary" : string { get id "summary:get"; }
|
||||
queryable value title id "title" : string { get id "title:get"; set id "title:set"; watch start id "watch" stop id "stop"; }
|
||||
queryable value summary id "summary" : string { get id "summary:get"; }
|
||||
}`,
|
||||
{ source },
|
||||
);
|
||||
@@ -22,11 +23,19 @@ test("React bindings preserve read-only, writable and nested reference contracts
|
||||
const pkg = compileCapabilityResourceSource(
|
||||
`import interface Fields; package P id "p" revision "p@1" {
|
||||
function props id "props" : unit -> record {fields: interface-ref<Fields>; caption: string;};
|
||||
query Editor id "editor" root Fields document "editor.graphql" operation "Editor" {max rows 1; watch;}
|
||||
}`,
|
||||
{ source, environment: { interfaces: new Map([["Fields", iface.resource.revision]]) } },
|
||||
);
|
||||
assert.ok(pkg.ok && pkg.resource.kind === "package");
|
||||
if (!pkg.ok || pkg.resource.kind !== "package") throw new Error("package failed");
|
||||
pkg.resource.revision.checkedQueries = [
|
||||
await compileQuery(
|
||||
pkg.resource.revision.queries![0]!,
|
||||
[iface.resource.revision],
|
||||
async () => "query Editor {root {title @live summary @live plain: title}}",
|
||||
),
|
||||
];
|
||||
const schema = {
|
||||
format: "quixos-bindings",
|
||||
version: 1,
|
||||
@@ -68,7 +77,14 @@ test("React bindings preserve read-only, writable and nested reference contracts
|
||||
path.join(root, "consumer.ts"),
|
||||
`import {useLiveField, tryConform, type ReadableField, type WritableField} from "@quixos/web-studio-react-runtime";
|
||||
import {reactInterfaces} from "./react-props.gen.js";
|
||||
import type {ReactResults} from "./react-props.gen.js";
|
||||
import type {ReactResults, QueryResults} from "./react-props.gen.js";
|
||||
declare const query: QueryResults["Editor"];
|
||||
useLiveField(query.root.title).set("new");
|
||||
// @ts-expect-error live query fields retain exact setter types
|
||||
useLiveField(query.root.title).set(123);
|
||||
// @ts-expect-error readonly query fields do not acquire a setter
|
||||
useLiveField(query.root.summary).set("no");
|
||||
const plain: string = query.root.plain;
|
||||
async function lookup() {
|
||||
const view = await tryConform("object", reactInterfaces.Fields);
|
||||
if (!view) return;
|
||||
@@ -79,14 +95,14 @@ async function lookup() {
|
||||
await view.call["summary.set"]("no setter");
|
||||
}
|
||||
declare const props: ReactResults["props"];
|
||||
const [title, setTitle] = useLiveField(props.fields.fields.title);
|
||||
setTitle("new");
|
||||
const title = useLiveField(props.fields.fields.title);
|
||||
title.set("new");
|
||||
// @ts-expect-error wrong setter value
|
||||
setTitle(123);
|
||||
title.set(123);
|
||||
// @ts-expect-error read-only hook has no setter
|
||||
const [summary, setSummary] = useLiveField(props.fields.fields.summary);
|
||||
const [manual, write] = useLiveField(props.fields.fields.summary, {write: async (value: string) => {}});
|
||||
write("new");
|
||||
useLiveField(props.fields.fields.summary).set("no");
|
||||
const manual = useLiveField(props.fields.fields.summary, {id: "manual", write: async (value: string) => {}});
|
||||
manual.set("new");
|
||||
const readonly: ReadableField<string> = props.fields.fields.title;
|
||||
// @ts-expect-error read-only does not satisfy writable
|
||||
const writable: WritableField<string> = props.fields.fields.summary;
|
||||
@@ -94,7 +110,7 @@ declare const narrow: WritableField<"only">;
|
||||
// @ts-expect-error writable references are invariant
|
||||
const widened: WritableField<string> = narrow;
|
||||
// @ts-expect-error callbacks must accept the field's type
|
||||
useLiveField(props.fields.fields.summary, {write: async (value: number) => {}});
|
||||
useLiveField(props.fields.fields.summary, {id: "manual", write: async (value: number) => {}});
|
||||
`,
|
||||
);
|
||||
const result = spawnSync(
|
||||
|
||||
Reference in New Issue
Block a user