@jigs.design/protocol 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/diagnostics.d.ts +1 -1
- package/dist/diagnostics.js +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -2
- package/dist/parse.d.ts +9 -1
- package/dist/parse.js +70 -2
- package/dist/types.d.ts +95 -6
- package/package.json +1 -1
package/dist/diagnostics.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* - `error`: what the model wrote is wrong there. The program still runs,
|
|
11
11
|
* with that part dropped or replaced, but the turn is not valid: the server
|
|
12
|
-
* asks the model for a repair, and a strict compile (a
|
|
12
|
+
* asks the model for a repair, and a strict compile (a page, a
|
|
13
13
|
* situation's example, `jigs.compile`) fails.
|
|
14
14
|
* - `warning`: the source itself may be fine, but it was written for a
|
|
15
15
|
* language or catalog newer than this server's, so it may not mean what it
|
package/dist/diagnostics.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* - `error`: what the model wrote is wrong there. The program still runs,
|
|
11
11
|
* with that part dropped or replaced, but the turn is not valid: the server
|
|
12
|
-
* asks the model for a repair, and a strict compile (a
|
|
12
|
+
* asks the model for a repair, and a strict compile (a page, a
|
|
13
13
|
* situation's example, `jigs.compile`) fails.
|
|
14
14
|
* - `warning`: the source itself may be fine, but it was written for a
|
|
15
15
|
* language or catalog newer than this server's, so it may not mean what it
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Diagnostic, DiagnosticFix, Severity, Span, severities } from "./diagnostics.js";
|
|
2
|
-
import { ChatBlock, ChatBlockStatus, ChildrenKind, ComponentSchema, Invalidation, JigsErrorCode, JigsErrorData, JsonValue, Message, NumberPropSchema, PROGRAM_FORMAT, ProcedureEntry, ProcedureKind, Program, PropSchema, SessionBody, SessionEvent, SessionOptions, jigsErrorCodes } from "./types.js";
|
|
2
|
+
import { ChatBlock, ChatBlockStatus, ChildrenKind, ComponentSchema, Invalidation, JigsErrorCode, JigsErrorData, JsonValue, Message, NumberPropSchema, PROGRAM_FORMAT, PageInvalidation, PageProps, PageRef, PageReply, ProcedureEntry, ProcedureKind, Program, PropSchema, PushEvent, SessionBody, SessionDocument, SessionEvent, SessionOptions, jigsErrorCodes } from "./types.js";
|
|
3
3
|
import { FrameMessage, HostMessage, MutationCall, MutationResult, Op, QueryRead, QueryResult, ROOT_ID, Row, RuntimeError, WireArg, WireProps, WireValue, WorkerMessage } from "./protocol.js";
|
|
4
|
-
import { parseErrorData, parseInvalidations, parseProgram, parseSessionEvent } from "./parse.js";
|
|
4
|
+
import { parseErrorData, parseInvalidations, parsePageReply, parseProgram, parsePushEvent, parseSessionEvent } from "./parse.js";
|
|
5
5
|
import { isAllowedImage, isAllowedLink, isImageHostEntry, normalizeImageHost } from "./urls.js";
|
|
6
|
-
export { type ChatBlock, type ChatBlockStatus, type ChildrenKind, type ComponentSchema, type Diagnostic, type DiagnosticFix, type FrameMessage, type HostMessage, type Invalidation, type JigsErrorCode, type JigsErrorData, type JsonValue, type Message, type MutationCall, type MutationResult, type NumberPropSchema, type Op, PROGRAM_FORMAT, type ProcedureEntry, type ProcedureKind, type Program, type PropSchema, type QueryRead, type QueryResult, ROOT_ID, type Row, type RuntimeError, type SessionBody, type SessionEvent, type SessionOptions, type Severity, type Span, type WireArg, type WireProps, type WireValue, type WorkerMessage, isAllowedImage, isAllowedLink, isImageHostEntry, jigsErrorCodes, normalizeImageHost, parseErrorData, parseInvalidations, parseProgram, parseSessionEvent, severities };
|
|
6
|
+
export { type ChatBlock, type ChatBlockStatus, type ChildrenKind, type ComponentSchema, type Diagnostic, type DiagnosticFix, type FrameMessage, type HostMessage, type Invalidation, type JigsErrorCode, type JigsErrorData, type JsonValue, type Message, type MutationCall, type MutationResult, type NumberPropSchema, type Op, PROGRAM_FORMAT, type PageInvalidation, type PageProps, type PageRef, type PageReply, type ProcedureEntry, type ProcedureKind, type Program, type PropSchema, type PushEvent, type QueryRead, type QueryResult, ROOT_ID, type Row, type RuntimeError, type SessionBody, type SessionDocument, type SessionEvent, type SessionOptions, type Severity, type Span, type WireArg, type WireProps, type WireValue, type WorkerMessage, isAllowedImage, isAllowedLink, isImageHostEntry, jigsErrorCodes, normalizeImageHost, parseErrorData, parseInvalidations, parsePageReply, parseProgram, parsePushEvent, parseSessionEvent, severities };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PROGRAM_FORMAT, jigsErrorCodes } from "./types.js";
|
|
2
2
|
import { severities } from "./diagnostics.js";
|
|
3
3
|
import { ROOT_ID } from "./protocol.js";
|
|
4
|
-
import { parseErrorData, parseInvalidations, parseProgram, parseSessionEvent } from "./parse.js";
|
|
4
|
+
import { parseErrorData, parseInvalidations, parsePageReply, parseProgram, parsePushEvent, parseSessionEvent } from "./parse.js";
|
|
5
5
|
import { isAllowedImage, isAllowedLink, isImageHostEntry, normalizeImageHost } from "./urls.js";
|
|
6
|
-
export { PROGRAM_FORMAT, ROOT_ID, isAllowedImage, isAllowedLink, isImageHostEntry, jigsErrorCodes, normalizeImageHost, parseErrorData, parseInvalidations, parseProgram, parseSessionEvent, severities };
|
|
6
|
+
export { PROGRAM_FORMAT, ROOT_ID, isAllowedImage, isAllowedLink, isImageHostEntry, jigsErrorCodes, normalizeImageHost, parseErrorData, parseInvalidations, parsePageReply, parseProgram, parsePushEvent, parseSessionEvent, severities };
|
package/dist/parse.d.ts
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { Invalidation, JigsErrorData, Program, SessionEvent } from "./types.js";
|
|
1
|
+
import { Invalidation, JigsErrorData, PageReply, Program, PushEvent, SessionEvent } from "./types.js";
|
|
2
2
|
//#region src/parse.d.ts
|
|
3
3
|
export declare function parseErrorData(value: unknown): JigsErrorData | null;
|
|
4
4
|
/** The `invalidate` list of a mutation's reply. */
|
|
5
5
|
export declare function parseInvalidations(value: unknown): ReadonlyArray<Invalidation> | null;
|
|
6
6
|
export declare function parseProgram(value: unknown): Program | null;
|
|
7
|
+
/** A page request's reply body, or null when it is not one. */
|
|
8
|
+
export declare function parsePageReply(value: unknown): PageReply | null;
|
|
7
9
|
/** One session event from its JSON text, or null when it is not one. */
|
|
8
10
|
export declare function parseSessionEvent(text: string): SessionEvent | null;
|
|
11
|
+
/**
|
|
12
|
+
* One event of the push stream from its JSON text, or null when it is not
|
|
13
|
+
* one the server may send. `open` and `version` come from the transport,
|
|
14
|
+
* never the wire, so they are null here.
|
|
15
|
+
*/
|
|
16
|
+
export declare function parsePushEvent(text: string): PushEvent | null;
|
|
9
17
|
//#endregion
|
package/dist/parse.js
CHANGED
|
@@ -41,6 +41,27 @@ function parseInvalidations(value) {
|
|
|
41
41
|
}
|
|
42
42
|
return out;
|
|
43
43
|
}
|
|
44
|
+
const isScalar = (value) => typeof value === "boolean" || typeof value === "number" || typeof value === "string";
|
|
45
|
+
function parsePageInvalidation(value) {
|
|
46
|
+
if (!isRecord(value) || !isString(value.name)) return null;
|
|
47
|
+
if (!("props" in value)) return { name: value.name };
|
|
48
|
+
const props = recordOf(value.props, (entry) => isScalar(entry) ? entry : null);
|
|
49
|
+
return props === null ? null : {
|
|
50
|
+
name: value.name,
|
|
51
|
+
props
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** The `pages` list of an `invalidate-pages` event. */
|
|
55
|
+
function parsePageInvalidations(value) {
|
|
56
|
+
if (!Array.isArray(value)) return null;
|
|
57
|
+
const out = [];
|
|
58
|
+
for (const entry of value) {
|
|
59
|
+
const parsed = parsePageInvalidation(entry);
|
|
60
|
+
if (parsed === null) return null;
|
|
61
|
+
out.push(parsed);
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
44
65
|
function parsePropSchema(value) {
|
|
45
66
|
if (!isRecord(value)) return null;
|
|
46
67
|
switch (value.kind) {
|
|
@@ -111,6 +132,17 @@ function parseDiagnostics(value) {
|
|
|
111
132
|
return parsed === null ? [] : [parsed];
|
|
112
133
|
});
|
|
113
134
|
}
|
|
135
|
+
/** A page request's reply body, or null when it is not one. */
|
|
136
|
+
function parsePageReply(value) {
|
|
137
|
+
if (!isRecord(value) || !isString(value.version)) return null;
|
|
138
|
+
const program = parseProgram(value.program);
|
|
139
|
+
const diagnostics = parseDiagnostics(value.diagnostics);
|
|
140
|
+
return program === null || diagnostics === null ? null : {
|
|
141
|
+
diagnostics,
|
|
142
|
+
program,
|
|
143
|
+
version: value.version
|
|
144
|
+
};
|
|
145
|
+
}
|
|
114
146
|
/** One session event from its JSON text, or null when it is not one. */
|
|
115
147
|
function parseSessionEvent(text) {
|
|
116
148
|
let value;
|
|
@@ -139,7 +171,13 @@ function parseSessionEvent(text) {
|
|
|
139
171
|
type: "program"
|
|
140
172
|
};
|
|
141
173
|
}
|
|
142
|
-
if (value.type === "done" && isString(value.source)) return {
|
|
174
|
+
if (value.type === "done" && isString(value.source)) return isString(value.reply) ? {
|
|
175
|
+
diagnostics,
|
|
176
|
+
reply: value.reply,
|
|
177
|
+
revision: value.revision,
|
|
178
|
+
source: value.source,
|
|
179
|
+
type: "done"
|
|
180
|
+
} : {
|
|
143
181
|
diagnostics,
|
|
144
182
|
revision: value.revision,
|
|
145
183
|
source: value.source,
|
|
@@ -147,5 +185,35 @@ function parseSessionEvent(text) {
|
|
|
147
185
|
};
|
|
148
186
|
return null;
|
|
149
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* One event of the push stream from its JSON text, or null when it is not
|
|
190
|
+
* one the server may send. `open` and `version` come from the transport,
|
|
191
|
+
* never the wire, so they are null here.
|
|
192
|
+
*/
|
|
193
|
+
function parsePushEvent(text) {
|
|
194
|
+
let value;
|
|
195
|
+
try {
|
|
196
|
+
value = JSON.parse(text);
|
|
197
|
+
} catch {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
if (!isRecord(value)) return null;
|
|
201
|
+
if (value.type === "close") return { type: "close" };
|
|
202
|
+
if (value.type === "invalidate") {
|
|
203
|
+
const invalidate = parseInvalidations(value.invalidate);
|
|
204
|
+
return invalidate === null ? null : {
|
|
205
|
+
invalidate,
|
|
206
|
+
type: "invalidate"
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
if (value.type === "invalidate-pages") {
|
|
210
|
+
const pages = parsePageInvalidations(value.pages);
|
|
211
|
+
return pages === null ? null : {
|
|
212
|
+
pages,
|
|
213
|
+
type: "invalidate-pages"
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
150
218
|
//#endregion
|
|
151
|
-
export { parseErrorData, parseInvalidations, parseProgram, parseSessionEvent };
|
|
219
|
+
export { parseErrorData, parseInvalidations, parsePageReply, parseProgram, parsePushEvent, parseSessionEvent };
|
package/dist/types.d.ts
CHANGED
|
@@ -51,10 +51,35 @@ export interface ProcedureEntry {
|
|
|
51
51
|
* data. Without `input`, every input of the query refetches. With it, only
|
|
52
52
|
* the queries whose input contains those values.
|
|
53
53
|
*/
|
|
54
|
-
export interface Invalidation {
|
|
54
|
+
export interface Invalidation<TName extends string = string> {
|
|
55
55
|
input?: JsonValue;
|
|
56
|
-
name:
|
|
56
|
+
name: TName;
|
|
57
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* What the push channel carries. The server sends `invalidate` (the queries
|
|
60
|
+
* to refetch, by name), `invalidate-pages` (the pages to refetch, by name)
|
|
61
|
+
* and `close` (it is ending the stream on purpose, so the next connection is
|
|
62
|
+
* no gap). The transport adds `open` on every connection it makes, with
|
|
63
|
+
* `replayed` true when it asked the server to resume from the last event
|
|
64
|
+
* id, and `version`, the server's `jigs-version` on that connection. A
|
|
65
|
+
* server cannot send `open` or `version`. No event carries a program: a
|
|
66
|
+
* page refetches its own.
|
|
67
|
+
*/
|
|
68
|
+
export type PushEvent = {
|
|
69
|
+
invalidate: ReadonlyArray<Invalidation>;
|
|
70
|
+
type: "invalidate";
|
|
71
|
+
} | {
|
|
72
|
+
pages: ReadonlyArray<PageInvalidation>;
|
|
73
|
+
type: "invalidate-pages";
|
|
74
|
+
} | {
|
|
75
|
+
replayed: boolean;
|
|
76
|
+
type: "open";
|
|
77
|
+
} | {
|
|
78
|
+
type: "close";
|
|
79
|
+
} | {
|
|
80
|
+
type: "version";
|
|
81
|
+
version: string;
|
|
82
|
+
};
|
|
58
83
|
/**
|
|
59
84
|
* A compiled spec. Opaque to apps: pass it from the server to the view and
|
|
60
85
|
* nowhere else. The view trusts its schemas and image hosts.
|
|
@@ -70,6 +95,10 @@ export interface Program {
|
|
|
70
95
|
/** Text nodes pulled out of the code, so a prose edit swaps a table. */
|
|
71
96
|
prose: Readonly<Record<string, string>>;
|
|
72
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* One message of a session's conversation: the user's ask, or the model's
|
|
100
|
+
* reply as it wrote it. The current UI travels beside it, as `document`.
|
|
101
|
+
*/
|
|
73
102
|
export interface Message {
|
|
74
103
|
content: string;
|
|
75
104
|
role: "assistant" | "user";
|
|
@@ -87,13 +116,52 @@ export type SessionEvent = {
|
|
|
87
116
|
type: "program";
|
|
88
117
|
} | {
|
|
89
118
|
diagnostics: ReadonlyArray<Diagnostic>;
|
|
119
|
+
/**
|
|
120
|
+
* The assistant's message for the conversation, absent when no model
|
|
121
|
+
* ran: the reply as written when the turn took one round and the
|
|
122
|
+
* server did not reorder it, otherwise the checked source.
|
|
123
|
+
*/
|
|
124
|
+
reply?: string;
|
|
90
125
|
revision: number;
|
|
126
|
+
/** The new document: the checked source, with its pragma. */
|
|
91
127
|
source: string;
|
|
92
128
|
type: "done";
|
|
93
129
|
} | {
|
|
94
130
|
error: JigsErrorData;
|
|
95
131
|
type: "error";
|
|
96
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* A page's props. Scalars only: the compiler types a prop only when it is
|
|
135
|
+
* a literal, and a define cannot declare an object prop.
|
|
136
|
+
*/
|
|
137
|
+
export type PageProps = Readonly<Record<string, boolean | number | string>>;
|
|
138
|
+
/** A page of the host and the props it was asked for. */
|
|
139
|
+
export interface PageRef {
|
|
140
|
+
/** The page jig's name. */
|
|
141
|
+
name: string;
|
|
142
|
+
/** Its props, keys sorted. */
|
|
143
|
+
props: PageProps;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* One page a push event refreshes, by name. Without `props`, every props of
|
|
147
|
+
* the page refetches; with them, only the pages whose props contain those
|
|
148
|
+
* values, as an `Invalidation`'s `input` matches.
|
|
149
|
+
*/
|
|
150
|
+
export interface PageInvalidation<TName extends string = string> {
|
|
151
|
+
name: TName;
|
|
152
|
+
props?: PageProps;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* The answer to a page request, `POST { type: "page", name, props }`: the
|
|
156
|
+
* page's program, its diagnostics (a saved page is compiled leniently, so
|
|
157
|
+
* they may hold errors), and the server's `jigs-version`, so a client can
|
|
158
|
+
* drop programs an older server compiled.
|
|
159
|
+
*/
|
|
160
|
+
export interface PageReply {
|
|
161
|
+
diagnostics: ReadonlyArray<Diagnostic>;
|
|
162
|
+
program: Program;
|
|
163
|
+
version: string;
|
|
164
|
+
}
|
|
97
165
|
/**
|
|
98
166
|
* Where a chat block is: still arriving, being repaired after it closed with
|
|
99
167
|
* errors, or final.
|
|
@@ -109,15 +177,23 @@ export interface ChatBlock {
|
|
|
109
177
|
diagnostics: ReadonlyArray<Diagnostic>;
|
|
110
178
|
/** Set when the block could not be built, e.g. an edit to a missing UI. */
|
|
111
179
|
error?: JigsErrorData;
|
|
112
|
-
/**
|
|
113
|
-
id: string;
|
|
114
|
-
/** `${id}@${version}`: unique in a conversation. */
|
|
180
|
+
/** `${name}@${version}`: unique in a conversation. */
|
|
115
181
|
key: string;
|
|
182
|
+
/**
|
|
183
|
+
* The fence id the model gave the block, e.g. "monthly-spending": the
|
|
184
|
+
* jig's name in the conversation's scope.
|
|
185
|
+
*/
|
|
186
|
+
name: string;
|
|
116
187
|
program: Program;
|
|
188
|
+
/**
|
|
189
|
+
* Set when the whole block is one tag naming a page of the host, with
|
|
190
|
+
* literal props: the block is that page, so the app can link to it.
|
|
191
|
+
*/
|
|
192
|
+
ref?: PageRef;
|
|
117
193
|
/** The checked source, with its pragma. Store this, not the program. */
|
|
118
194
|
source: string;
|
|
119
195
|
status: ChatBlockStatus;
|
|
120
|
-
/** 1 for the first block with this
|
|
196
|
+
/** 1 for the first block with this name in the conversation, then 2, 3… */
|
|
121
197
|
version: number;
|
|
122
198
|
}
|
|
123
199
|
/** A value that travels as JSON. */
|
|
@@ -126,8 +202,21 @@ export type JsonValue = boolean | null | number | string | ReadonlyArray<JsonVal
|
|
|
126
202
|
};
|
|
127
203
|
/** App options sent with a turn; the server parses them with its `options` schema. */
|
|
128
204
|
export type SessionOptions = Readonly<Record<string, JsonValue>>;
|
|
205
|
+
/**
|
|
206
|
+
* What a session is about: an inline source, or a page the server serves,
|
|
207
|
+
* by name, opened as a document.
|
|
208
|
+
*/
|
|
209
|
+
export type SessionDocument = {
|
|
210
|
+
source: string;
|
|
211
|
+
} | {
|
|
212
|
+
name: string;
|
|
213
|
+
props?: PageProps;
|
|
214
|
+
};
|
|
129
215
|
/** What a session request carries. */
|
|
130
216
|
export interface SessionBody {
|
|
217
|
+
/** The current UI. Absent when the turn writes a new one. */
|
|
218
|
+
document?: SessionDocument;
|
|
219
|
+
/** The conversation about it: the user's asks and the model's replies. */
|
|
131
220
|
messages: ReadonlyArray<Message>;
|
|
132
221
|
options?: SessionOptions;
|
|
133
222
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jigs.design/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "The program format, the diagnostics, and the types and messages the server, the browser and the sandbox share. No runtime and no dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|