@volter/world-core 2.0.36 → 3.0.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/README.md +4 -5
- package/app-route.cjs +12 -6
- package/app-route.d.cts +1 -1
- package/dist/app-route.cjs +12 -6
- package/dist/app-route.d.cts +1 -1
- package/dist/generated/pack-facts.json +1410 -3069
- package/dist/inject.cjs +64 -9
- package/dist/pack-facts.cjs +44 -0
- package/dist/src/actions.d.ts +3 -3
- package/dist/src/actions.js +22 -16
- package/dist/src/ancestry.d.ts +14 -2
- package/dist/src/ancestry.js +92 -2
- package/dist/src/anthropic-wire.d.ts +39 -0
- package/dist/src/anthropic-wire.js +136 -0
- package/dist/src/bytes.d.ts +7 -0
- package/dist/src/bytes.js +35 -0
- package/dist/src/changeset.d.ts +1 -1
- package/dist/src/changeset.js +0 -0
- package/dist/src/clickhouse/index.d.ts +3 -0
- package/dist/src/clickhouse/index.js +6 -0
- package/dist/src/clickhouse/sql.d.ts +233 -0
- package/dist/src/clickhouse/sql.js +4329 -0
- package/dist/src/clickhouse/types.d.ts +18 -0
- package/dist/src/clickhouse/types.js +47 -0
- package/dist/src/clickhouse/values.d.ts +146 -0
- package/dist/src/clickhouse/values.js +858 -0
- package/dist/src/client-bundle.js +2 -3
- package/dist/src/cors.d.ts +15 -0
- package/dist/src/cors.js +31 -0
- package/dist/src/derived-core.d.ts +487 -24
- package/dist/src/derived-core.js +788 -144
- package/dist/src/derived-real.d.ts +13 -0
- package/dist/src/derived-real.js +518 -0
- package/dist/src/derived.d.ts +35 -1
- package/dist/src/derived.js +61 -9
- package/dist/src/emit.js +1 -2
- package/dist/src/events.d.ts +206 -0
- package/dist/src/events.js +341 -0
- package/dist/src/executor.d.ts +3 -0
- package/dist/src/executor.js +19 -2
- package/dist/src/file-response.d.ts +6 -0
- package/dist/src/file-response.js +30 -0
- package/dist/src/fork.js +3 -2
- package/dist/src/git/history.d.ts +7 -0
- package/dist/src/git/history.js +24 -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 +28 -0
- package/dist/src/git/lfs.js +66 -0
- package/dist/src/git/objects.js +3 -8
- package/dist/src/git/smart-http.d.ts +3 -1
- package/dist/src/git/smart-http.js +67 -6
- package/dist/src/graphql-wire.d.ts +29 -0
- package/dist/src/graphql-wire.js +101 -0
- package/dist/src/grpc-wire.d.ts +67 -0
- package/dist/src/grpc-wire.js +170 -0
- package/dist/src/h2.d.ts +40 -0
- package/dist/src/h2.js +656 -0
- package/dist/src/head.d.ts +32 -3
- package/dist/src/head.js +161 -40
- package/dist/src/history.d.ts +1 -1
- package/dist/src/history.js +6 -6
- package/dist/src/hpack.json +1 -0
- package/dist/src/index.d.ts +64 -75
- package/dist/src/index.js +58 -101
- package/dist/src/log.js +28 -19
- package/dist/src/machines.d.ts +50 -0
- package/dist/src/machines.js +151 -0
- package/dist/src/managed-database.d.ts +86 -0
- package/dist/src/managed-database.js +283 -0
- package/dist/src/multipart.d.ts +11 -0
- package/dist/src/multipart.js +51 -0
- package/dist/src/observe.d.ts +15 -5
- package/dist/src/observe.js +23 -9
- package/dist/src/openai-wire.d.ts +108 -0
- package/dist/src/openai-wire.js +337 -0
- package/dist/src/pack-assets.d.ts +3 -4
- package/dist/src/pack-assets.js +15 -10
- package/dist/src/pack-fetch.d.ts +77 -0
- package/dist/src/pack-fetch.js +449 -0
- package/dist/src/pack-paths.d.ts +12 -0
- package/dist/src/pack-paths.js +86 -0
- package/dist/src/packRegistry.d.ts +69 -162
- package/dist/src/packRegistry.js +55 -20
- package/dist/src/people.d.ts +13 -0
- package/dist/src/people.js +18 -0
- package/dist/src/placeholder-image.d.ts +5 -0
- package/dist/src/placeholder-image.js +114 -0
- package/dist/src/protobuf.d.ts +28 -0
- package/dist/src/protobuf.js +332 -0
- package/dist/src/redis/engine.js +1 -1
- package/dist/src/request-scope.d.ts +1 -1
- package/dist/src/request-scope.js +6 -4
- package/dist/src/resource-blob.d.ts +5 -0
- package/dist/src/resource-blob.js +11 -0
- package/dist/src/runtime.d.ts +85 -0
- package/dist/src/runtime.js +104 -0
- package/dist/src/s3/wire.d.ts +60 -0
- package/dist/src/s3/wire.js +157 -0
- package/dist/src/scenario.d.ts +3 -0
- package/dist/src/scenario.js +2 -0
- package/dist/src/schema-sample.d.ts +1 -0
- package/dist/src/schema-sample.js +21 -0
- package/dist/src/sealed-box.d.ts +14 -0
- package/dist/src/sealed-box.js +225 -0
- package/dist/src/serve-http.d.ts +14 -0
- package/dist/src/serve-http.js +27 -3
- package/dist/src/serve.d.ts +6 -0
- package/dist/src/serve.js +69 -14
- package/dist/src/signing.d.ts +135 -0
- package/dist/src/signing.js +222 -0
- package/dist/src/sigv4.d.ts +48 -0
- package/dist/src/sigv4.js +167 -0
- package/dist/src/smtp.d.ts +16 -0
- package/dist/src/smtp.js +72 -0
- package/dist/src/sockets.d.ts +51 -0
- package/dist/src/sockets.js +90 -0
- package/dist/src/state-system.d.ts +1 -0
- package/dist/src/state-system.js +1 -1
- package/dist/src/storage.d.ts +1 -1
- package/dist/src/storage.js +3 -3
- package/dist/src/trace-context.js +1 -1
- package/dist/src/twin-fetch.d.ts +0 -7
- package/dist/src/twin-fetch.js +0 -14
- package/dist/src/vendor-call.d.ts +6 -0
- package/dist/src/vendor-call.js +41 -0
- package/dist/src/world-store.js +1 -1
- package/dist/vendor-hosts.cjs +36 -125
- package/dist/vendor-hosts.d.cts +8 -0
- package/generated/pack-facts.json +1410 -3069
- package/inject.cjs +64 -9
- package/pack-facts.cjs +44 -0
- package/package.json +17 -3
- package/src/actions.ts +23 -16
- package/src/ancestry.ts +74 -2
- package/src/anthropic-wire.ts +137 -0
- package/src/bytes.ts +42 -0
- package/src/changeset.ts +5 -5
- package/src/clickhouse/index.ts +6 -0
- package/src/clickhouse/sql.ts +3059 -0
- package/src/clickhouse/types.ts +44 -0
- package/src/clickhouse/values.ts +697 -0
- package/src/client-bundle.ts +2 -3
- package/src/cors.ts +34 -0
- package/src/derived-core.ts +1013 -146
- package/src/derived-real.ts +434 -0
- package/src/derived.ts +73 -3
- package/src/emit.ts +1 -2
- package/src/events.ts +449 -0
- package/src/executor.ts +24 -2
- package/src/file-response.ts +27 -0
- package/src/fork.ts +3 -2
- package/src/git/history.ts +19 -0
- package/src/git/index.ts +1 -0
- package/src/git/lfs.ts +67 -0
- package/src/git/objects.ts +3 -5
- package/src/git/smart-http.ts +56 -6
- package/src/graphql-wire.ts +106 -0
- package/src/grpc-wire.ts +159 -0
- package/src/h2.ts +627 -0
- package/src/head.ts +132 -41
- package/src/history.ts +6 -6
- package/src/hpack.json +1 -0
- package/src/index.ts +82 -329
- package/src/log.ts +27 -18
- package/src/machines.ts +151 -0
- package/src/managed-database.ts +299 -0
- package/src/multipart.ts +51 -0
- package/src/observe.ts +31 -15
- package/src/openai-wire.ts +371 -0
- package/src/pack-assets.ts +15 -11
- package/src/pack-fetch.ts +458 -0
- package/src/pack-paths.ts +72 -0
- package/src/packRegistry.ts +79 -167
- package/src/people.ts +31 -0
- package/src/placeholder-image.ts +88 -0
- package/src/protobuf.ts +251 -0
- package/src/redis/engine.ts +1 -1
- package/src/request-scope.ts +8 -4
- package/src/resource-blob.ts +13 -0
- package/src/runtime.ts +344 -0
- package/src/s3/wire.ts +172 -0
- package/src/scenario.ts +4 -0
- package/src/schema-sample.ts +24 -0
- package/src/sealed-box.ts +182 -0
- package/src/serve-http.ts +31 -3
- package/src/serve.ts +58 -14
- package/src/signing.ts +231 -0
- package/src/sigv4.ts +158 -0
- package/src/smtp.ts +76 -0
- package/src/sockets.ts +140 -0
- package/src/state-system.ts +2 -2
- package/src/storage.ts +3 -3
- package/src/trace-context.ts +1 -1
- package/src/twin-fetch.ts +0 -20
- package/src/vendor-call.ts +41 -0
- package/src/world-store.ts +1 -1
- package/vendor-hosts.cjs +36 -125
- package/vendor-hosts.d.cts +8 -0
- package/dist/src/mirror-shell.d.ts +0 -2
- package/dist/src/mirror-shell.js +0 -13
- package/dist/src/v1-removed.d.ts +0 -159
- package/dist/src/v1-removed.js +0 -124
- package/src/mirror-shell.ts +0 -15
- package/src/v1-removed.ts +0 -172
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// Anthropic's Messages wire (architecture, "The kernel owns shared mechanics"): the Messages shapes a vendor serves as
|
|
2
|
+
// Anthropic defines them (https://platform.claude.com/docs/en/api/messages and /build-with-claude/streaming), for
|
|
3
|
+
// generative packs that run no model, beside the OpenAI wire (./openai-wire.ts) whose turn vocabulary it answers. A
|
|
4
|
+
// pack decides its turn (the World's scenario's, else the stub) and its own facts (its ids, its usage fields); this
|
|
5
|
+
// module reads a request as the scenario reads it and shapes the answer and its Server-Sent Events. Importing it does
|
|
6
|
+
// nothing.
|
|
7
|
+
import { estimateTokens, forbidsTools } from "./openai-wire.js";
|
|
8
|
+
import { sampleFromSchema } from "./schema-sample.js";
|
|
9
|
+
const obj = (v) => (v && typeof v === 'object' && !Array.isArray(v) ? v : {});
|
|
10
|
+
const arr = (v) => (Array.isArray(v) ? v : []);
|
|
11
|
+
/** A message's content as text: a string, or its text blocks (and the text of its tool results) joined. */
|
|
12
|
+
export const messagesText = (content) => typeof content === 'string' ? content : arr(content).map((c) => (c.type === 'text' ? String(c.text ?? '') : c.type === 'tool_result' ? messagesText(c.content) : '')).filter(Boolean).join('\n');
|
|
13
|
+
/** The last user message's text. */
|
|
14
|
+
export function messagesLastUserText(messages) {
|
|
15
|
+
for (let i = messages.length - 1; i >= 0; i--)
|
|
16
|
+
if (messages[i].role === 'user') {
|
|
17
|
+
const t = messagesText(messages[i].content);
|
|
18
|
+
if (t)
|
|
19
|
+
return t;
|
|
20
|
+
}
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
/** The tool results the last message carries, by the names of the tool_use blocks they answer. */
|
|
24
|
+
export function messagesToolResults(messages) {
|
|
25
|
+
const ids = arr(messages.at(-1)?.content).filter((c) => c.type === 'tool_result').map((c) => c.tool_use_id);
|
|
26
|
+
if (!ids.length)
|
|
27
|
+
return [];
|
|
28
|
+
return messages.flatMap((m) => arr(m.content)).filter((c) => c.type === 'tool_use' && ids.includes(c.id)).map((c) => String(c.name));
|
|
29
|
+
}
|
|
30
|
+
/** A Messages request as a scenario reads it (the OpenAI wire's `WireRequest`): its model, its system and messages'
|
|
31
|
+
* text, its last user text, the tools it offers and the tool results it ends with. */
|
|
32
|
+
export function messagesWireRequest(body) {
|
|
33
|
+
const messages = arr(body.messages);
|
|
34
|
+
const system = typeof body.system === 'string' ? body.system : messagesText(body.system);
|
|
35
|
+
return {
|
|
36
|
+
model: String(body.model ?? ''), text: [system, ...messages.map((m) => messagesText(m.content))].join('\n'), lastUser: messagesLastUserText(messages),
|
|
37
|
+
tools: arr(body.tools).map((t) => String(t.name ?? '')).filter(Boolean), results: messagesToolResults(messages),
|
|
38
|
+
...(forbidsTools(body.tool_choice) ? { toolsForbidden: true } : {}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
/** The labeled stub for a Messages request: with tools offered (`tool_choice` not `none`) and the last message not a
|
|
42
|
+
* tool's result, it calls the tool the choice names, else the first, with input its schema admits; with a JSON schema
|
|
43
|
+
* for the output, it answers a value the schema admits; otherwise it echoes the last user message. `label` names the
|
|
44
|
+
* twin. */
|
|
45
|
+
export function messagesStubTurn(body, label) {
|
|
46
|
+
const model = String(body.model);
|
|
47
|
+
const messages = arr(body.messages);
|
|
48
|
+
const tools = arr(body.tools).filter((t) => t.input_schema !== undefined);
|
|
49
|
+
const choice = obj(body.tool_choice ?? { type: 'auto' });
|
|
50
|
+
if (tools.length && choice.type !== 'none' && (messagesToolResults(messages).length === 0 || choice.type === 'any' || choice.type === 'tool')) {
|
|
51
|
+
const tool = (choice.type === 'tool' ? tools.find((t) => t.name === choice.name) : undefined) ?? tools[0];
|
|
52
|
+
return { toolCalls: [{ name: String(tool.name), arguments: sampleFromSchema(tool.input_schema, String(tool.name)) }] };
|
|
53
|
+
}
|
|
54
|
+
const format = obj(obj(body.output_config).format ?? body.output_format);
|
|
55
|
+
if (format.type === 'json_schema')
|
|
56
|
+
return { text: JSON.stringify(sampleFromSchema(format.schema)) };
|
|
57
|
+
const said = messagesLastUserText(messages).trim();
|
|
58
|
+
return { text: `[twin-stub:${model}] This is a deterministic stub from the ${label} (no model runs). Your last message: ${said.length > 200 ? `${said.slice(0, 200)}…` : said || '(empty)'}` };
|
|
59
|
+
}
|
|
60
|
+
/** The OpenAI wire's finish reasons as the Messages stop reasons they mean. */
|
|
61
|
+
const STOP = { stop: 'end_turn', length: 'max_tokens', tool_calls: 'tool_use', content_filter: 'refusal' };
|
|
62
|
+
/** A message (`type: message`): a thinking block when the request turns thinking on, then the
|
|
63
|
+
* text, then the tool_use blocks; its stop reason, and its usage estimated from the request and the answer. A text
|
|
64
|
+
* longer than `max_tokens` is cut there and stops `max_tokens`. */
|
|
65
|
+
export function message(s) {
|
|
66
|
+
const b = s.body;
|
|
67
|
+
// thinking blocks come only when the request turns thinking on; a turn's reasoning is then their text
|
|
68
|
+
const thinkingOn = ['enabled', 'adaptive'].includes(String(obj(b.thinking).type));
|
|
69
|
+
const max = typeof b.max_tokens === 'number' ? b.max_tokens : undefined;
|
|
70
|
+
let text = s.turn.text ?? undefined;
|
|
71
|
+
let cut = false;
|
|
72
|
+
if (text !== undefined && max !== undefined && estimateTokens(text) > max) {
|
|
73
|
+
text = text.slice(0, Math.max(1, max) * 4);
|
|
74
|
+
cut = true;
|
|
75
|
+
}
|
|
76
|
+
const content = [];
|
|
77
|
+
if (thinkingOn) {
|
|
78
|
+
const thinking = s.turn.reasoning ?? '[twin-stub] No model runs here, so there is no reasoning to show.';
|
|
79
|
+
content.push({ type: 'thinking', thinking, signature: s.signature ? s.signature(thinking) : '' });
|
|
80
|
+
}
|
|
81
|
+
if (text !== undefined)
|
|
82
|
+
content.push({ type: 'text', text });
|
|
83
|
+
(s.turn.toolCalls ?? []).forEach((c, i) => content.push({ type: 'tool_use', id: s.toolId(i), name: c.name, input: c.arguments ?? {} }));
|
|
84
|
+
const stop = cut ? 'max_tokens' : s.turn.finishReason ? (STOP[s.turn.finishReason] ?? s.turn.finishReason) : s.turn.toolCalls?.length ? 'tool_use' : 'end_turn';
|
|
85
|
+
const request = messagesWireRequest(b);
|
|
86
|
+
const output = estimateTokens(content.map((c) => (c.type === 'tool_use' ? JSON.stringify(c.input) : String(c.text ?? c.thinking ?? ''))).join(''));
|
|
87
|
+
return {
|
|
88
|
+
id: s.id, type: 'message', role: 'assistant', model: s.model, content, stop_reason: stop, stop_sequence: null,
|
|
89
|
+
usage: { input_tokens: estimateTokens(request.text), cache_creation_input_tokens: 0, cache_read_input_tokens: 0, output_tokens: output, ...(s.usage ?? {}) },
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
/** Text in the pieces a stream sends it in: a few words at a time. */
|
|
93
|
+
function pieces(text) {
|
|
94
|
+
const words = text.match(/\S+\s*|\s+/g) ?? [text];
|
|
95
|
+
const out = [];
|
|
96
|
+
for (let i = 0; i < words.length; i += 4)
|
|
97
|
+
out.push(words.slice(i, i + 4).join(''));
|
|
98
|
+
return out.length ? out : [''];
|
|
99
|
+
}
|
|
100
|
+
/** A message as the stream's events: message_start (its content empty), per block its start, deltas and stop (a ping
|
|
101
|
+
* after the first start), message_delta with the stop reason and the output usage, message_stop. `extra` adds fields
|
|
102
|
+
* a vendor puts on the two closing events (Merge's `routing`). */
|
|
103
|
+
export function messageSSE(m, extra = {}, options = {}) {
|
|
104
|
+
const events = [];
|
|
105
|
+
const send = (type, data) => { events.push(`event: ${type}\ndata: ${JSON.stringify({ type, ...data })}\n\n`); };
|
|
106
|
+
const usage = obj(m.usage);
|
|
107
|
+
send('message_start', { message: { ...m, content: [], stop_reason: null, stop_sequence: null, usage: { ...usage, output_tokens: 1 } } });
|
|
108
|
+
arr(m.content).forEach((block, index) => {
|
|
109
|
+
if (block.type === 'text') {
|
|
110
|
+
send('content_block_start', { index, content_block: { type: 'text', text: '' } });
|
|
111
|
+
if (index === 0 && options.ping !== false)
|
|
112
|
+
send('ping', {});
|
|
113
|
+
for (const piece of pieces(String(block.text)))
|
|
114
|
+
send('content_block_delta', { index, delta: { type: 'text_delta', text: piece } });
|
|
115
|
+
}
|
|
116
|
+
else if (block.type === 'thinking') {
|
|
117
|
+
send('content_block_start', { index, content_block: { type: 'thinking', thinking: '', signature: '' } });
|
|
118
|
+
if (index === 0 && options.ping !== false)
|
|
119
|
+
send('ping', {});
|
|
120
|
+
for (const piece of pieces(String(block.thinking)))
|
|
121
|
+
send('content_block_delta', { index, delta: { type: 'thinking_delta', thinking: piece } });
|
|
122
|
+
send('content_block_delta', { index, delta: { type: 'signature_delta', signature: block.signature } });
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
send('content_block_start', { index, content_block: { ...block, input: {} } });
|
|
126
|
+
if (index === 0 && options.ping !== false)
|
|
127
|
+
send('ping', {});
|
|
128
|
+
for (const piece of options.completeToolInput ? [JSON.stringify(block.input)] : pieces(JSON.stringify(block.input)))
|
|
129
|
+
send('content_block_delta', { index, delta: { type: 'input_json_delta', partial_json: piece } });
|
|
130
|
+
}
|
|
131
|
+
send('content_block_stop', { index });
|
|
132
|
+
});
|
|
133
|
+
send('message_delta', { delta: { stop_reason: m.stop_reason, stop_sequence: null }, usage: { output_tokens: usage.output_tokens }, ...extra });
|
|
134
|
+
send('message_stop', { ...extra });
|
|
135
|
+
return events.join('');
|
|
136
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** The bytes of a gzip member (a SARIF upload, a tarball's contents, a gzipped request body). */
|
|
2
|
+
export declare function gunzip(bytes: Uint8Array): Promise<Uint8Array>;
|
|
3
|
+
/** Bytes as a gzip member. */
|
|
4
|
+
export declare function gzip(bytes: Uint8Array): Promise<Uint8Array>;
|
|
5
|
+
/** Bytes as a zlib (deflate) member: git's object and pack framing. Reading one back is git/inflate.ts, which also
|
|
6
|
+
* reports how many bytes it consumed, since a packfile's objects sit one after another with no length. */
|
|
7
|
+
export declare function deflate(bytes: Uint8Array): Promise<Uint8Array>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// Bytes a vendor's wire carries compressed, as a handler reads them. Web-standard compression streams where the runtime
|
|
2
|
+
// has them (workerd, the browser, Node), so the kernel's root keeps no static import of Node's zlib — a browser client
|
|
3
|
+
// imports this module too. Bun has neither `CompressionStream` nor `DecompressionStream` (Bun 1.2.20:
|
|
4
|
+
// `bun -e "typeof CompressionStream"` prints `undefined`), and a local World is served by Bun, so there the builtin is
|
|
5
|
+
// reached the way the kernel reaches every builtin: `process.getBuiltinModule`, at call time, never at import (the seam
|
|
6
|
+
// serve-http.ts's `nodeBuiltin` uses).
|
|
7
|
+
function zlib(what) {
|
|
8
|
+
const get = globalThis.process?.getBuiltinModule;
|
|
9
|
+
if (typeof get !== 'function')
|
|
10
|
+
throw new Error(`${what}: this runtime has neither the compression streams nor node:zlib (process.getBuiltinModule)`);
|
|
11
|
+
return get('node:zlib');
|
|
12
|
+
}
|
|
13
|
+
async function streamed(bytes, stream) {
|
|
14
|
+
const piped = new Response(bytes).body.pipeThrough(stream);
|
|
15
|
+
return new Uint8Array(await new Response(piped).arrayBuffer());
|
|
16
|
+
}
|
|
17
|
+
/** The bytes of a gzip member (a SARIF upload, a tarball's contents, a gzipped request body). */
|
|
18
|
+
export async function gunzip(bytes) {
|
|
19
|
+
if (typeof DecompressionStream === 'function')
|
|
20
|
+
return streamed(bytes, new DecompressionStream('gzip'));
|
|
21
|
+
return new Uint8Array(zlib('gunzip').gunzipSync(bytes));
|
|
22
|
+
}
|
|
23
|
+
/** Bytes as a gzip member. */
|
|
24
|
+
export async function gzip(bytes) {
|
|
25
|
+
if (typeof CompressionStream === 'function')
|
|
26
|
+
return streamed(bytes, new CompressionStream('gzip'));
|
|
27
|
+
return new Uint8Array(zlib('gzip').gzipSync(bytes));
|
|
28
|
+
}
|
|
29
|
+
/** Bytes as a zlib (deflate) member: git's object and pack framing. Reading one back is git/inflate.ts, which also
|
|
30
|
+
* reports how many bytes it consumed, since a packfile's objects sit one after another with no length. */
|
|
31
|
+
export async function deflate(bytes) {
|
|
32
|
+
if (typeof CompressionStream === 'function')
|
|
33
|
+
return streamed(bytes, new CompressionStream('deflate'));
|
|
34
|
+
return new Uint8Array(zlib('deflate').deflateSync(bytes));
|
|
35
|
+
}
|
package/dist/src/changeset.d.ts
CHANGED
|
@@ -155,7 +155,7 @@ export type Changeset = {
|
|
|
155
155
|
contentHash: string;
|
|
156
156
|
at: string;
|
|
157
157
|
};
|
|
158
|
-
/**
|
|
158
|
+
/** Where the parent log stood when this was cut, per state service (its entry count):
|
|
159
159
|
* a rebase reads the parent's entries since here to name what moved under the changeset. Outside
|
|
160
160
|
* the hash (metadata of the cut, not of the change). */
|
|
161
161
|
cut?: Record<string, HistoryReference>;
|
package/dist/src/changeset.js
CHANGED
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// The kernel's ClickHouse® SQL engine (architecture, "The kernel owns shared mechanics"): parsed into an AST and evaluated
|
|
2
|
+
// over rows a pack supplies as a catalog of relations. Tinybird's pipes and PostHog's HogQL are ClickHouse SQL; each pack
|
|
3
|
+
// keeps its own front (Tinybird's templates, HogQL's tables and property access). Importing it does nothing.
|
|
4
|
+
export * from "./values.js";
|
|
5
|
+
export * from "./types.js";
|
|
6
|
+
export * from "./sql.js";
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { type IntervalUnit } from './values.js';
|
|
2
|
+
import { type ClickHouseColumn } from './types.js';
|
|
3
|
+
import { ClickHouseError } from './values.js';
|
|
4
|
+
export { ClickHouseError };
|
|
5
|
+
export type Expr = {
|
|
6
|
+
k: 'lit';
|
|
7
|
+
v: unknown;
|
|
8
|
+
type: string;
|
|
9
|
+
text: string;
|
|
10
|
+
} | {
|
|
11
|
+
k: 'id';
|
|
12
|
+
parts: string[];
|
|
13
|
+
} | {
|
|
14
|
+
k: 'star';
|
|
15
|
+
qualifier?: string;
|
|
16
|
+
} | {
|
|
17
|
+
k: 'fn';
|
|
18
|
+
name: string;
|
|
19
|
+
args: Expr[];
|
|
20
|
+
params?: Expr[];
|
|
21
|
+
distinct?: boolean;
|
|
22
|
+
} | {
|
|
23
|
+
k: 'lambda';
|
|
24
|
+
params: string[];
|
|
25
|
+
body: Expr;
|
|
26
|
+
} | {
|
|
27
|
+
k: 'bin';
|
|
28
|
+
op: string;
|
|
29
|
+
a: Expr;
|
|
30
|
+
b: Expr;
|
|
31
|
+
} | {
|
|
32
|
+
k: 'not';
|
|
33
|
+
a: Expr;
|
|
34
|
+
} | {
|
|
35
|
+
k: 'neg';
|
|
36
|
+
a: Expr;
|
|
37
|
+
} | {
|
|
38
|
+
k: 'isnull';
|
|
39
|
+
a: Expr;
|
|
40
|
+
not: boolean;
|
|
41
|
+
} | {
|
|
42
|
+
k: 'between';
|
|
43
|
+
a: Expr;
|
|
44
|
+
lo: Expr;
|
|
45
|
+
hi: Expr;
|
|
46
|
+
not: boolean;
|
|
47
|
+
} | {
|
|
48
|
+
k: 'case';
|
|
49
|
+
operand?: Expr;
|
|
50
|
+
whens: Array<[Expr, Expr]>;
|
|
51
|
+
else?: Expr;
|
|
52
|
+
} | {
|
|
53
|
+
k: 'alias';
|
|
54
|
+
name: string;
|
|
55
|
+
e: Expr;
|
|
56
|
+
} | {
|
|
57
|
+
k: 'subquery';
|
|
58
|
+
q: Query;
|
|
59
|
+
} | {
|
|
60
|
+
k: 'array';
|
|
61
|
+
items: Expr[];
|
|
62
|
+
} | {
|
|
63
|
+
k: 'tuple';
|
|
64
|
+
items: Expr[];
|
|
65
|
+
} | {
|
|
66
|
+
k: 'index';
|
|
67
|
+
a: Expr;
|
|
68
|
+
i: Expr;
|
|
69
|
+
} | {
|
|
70
|
+
k: 'interval';
|
|
71
|
+
n: Expr;
|
|
72
|
+
unit: IntervalUnit;
|
|
73
|
+
} | {
|
|
74
|
+
k: 'cast';
|
|
75
|
+
e: Expr;
|
|
76
|
+
type: string;
|
|
77
|
+
}
|
|
78
|
+
/** A ClickHouse query parameter `{name: Type}` (what `tb_secret` renders at publish). */
|
|
79
|
+
| {
|
|
80
|
+
k: 'param';
|
|
81
|
+
name: string;
|
|
82
|
+
type: string;
|
|
83
|
+
};
|
|
84
|
+
type JoinKind = 'inner' | 'left' | 'right' | 'full' | 'cross';
|
|
85
|
+
type Strictness = 'all' | 'any' | 'semi' | 'anti';
|
|
86
|
+
export type TableSource = {
|
|
87
|
+
kind: 'table';
|
|
88
|
+
name: string;
|
|
89
|
+
} | {
|
|
90
|
+
kind: 'sub';
|
|
91
|
+
query: Query;
|
|
92
|
+
};
|
|
93
|
+
export type FromItem = {
|
|
94
|
+
source: TableSource;
|
|
95
|
+
final: boolean;
|
|
96
|
+
alias?: string;
|
|
97
|
+
join?: {
|
|
98
|
+
kind: JoinKind;
|
|
99
|
+
strictness: Strictness;
|
|
100
|
+
on?: Expr;
|
|
101
|
+
using?: string[];
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export type OrderItem = {
|
|
105
|
+
e: Expr;
|
|
106
|
+
desc: boolean;
|
|
107
|
+
nullsFirst: boolean;
|
|
108
|
+
};
|
|
109
|
+
export type WithItem = {
|
|
110
|
+
name: string;
|
|
111
|
+
expr?: Expr;
|
|
112
|
+
query?: Query;
|
|
113
|
+
};
|
|
114
|
+
export type Select = {
|
|
115
|
+
with: WithItem[];
|
|
116
|
+
distinct: boolean;
|
|
117
|
+
items: Expr[];
|
|
118
|
+
from: FromItem[];
|
|
119
|
+
prewhere?: Expr;
|
|
120
|
+
where?: Expr;
|
|
121
|
+
groupBy: Expr[];
|
|
122
|
+
having?: Expr;
|
|
123
|
+
orderBy: OrderItem[];
|
|
124
|
+
limit?: Expr;
|
|
125
|
+
offset?: Expr;
|
|
126
|
+
};
|
|
127
|
+
export type Query = {
|
|
128
|
+
selects: Select[];
|
|
129
|
+
format?: string;
|
|
130
|
+
};
|
|
131
|
+
/** Parse one SQL statement (a SELECT, possibly with UNION ALL and a trailing FORMAT). */
|
|
132
|
+
export declare function parseSql(sql: string): Query;
|
|
133
|
+
/** A relation; `declared` marks a Data Source's own columns (their types are schema, not inference). */
|
|
134
|
+
export type Relation = {
|
|
135
|
+
columns: ClickHouseColumn[];
|
|
136
|
+
rows: unknown[][];
|
|
137
|
+
declared?: boolean;
|
|
138
|
+
};
|
|
139
|
+
/** Where a FROM name resolves: pipe nodes, Data Sources, CTEs. */
|
|
140
|
+
export interface Catalog {
|
|
141
|
+
/** A named relation, or undefined when the name is unknown. `final` requests FINAL semantics. */
|
|
142
|
+
table(name: string, final: boolean): Relation | undefined;
|
|
143
|
+
}
|
|
144
|
+
type Source = {
|
|
145
|
+
alias?: string;
|
|
146
|
+
name?: string;
|
|
147
|
+
columns: ClickHouseColumn[];
|
|
148
|
+
index: Map<string, number>;
|
|
149
|
+
declared?: boolean;
|
|
150
|
+
};
|
|
151
|
+
type JRow = unknown[][];
|
|
152
|
+
type Scope = {
|
|
153
|
+
sources: Source[];
|
|
154
|
+
usingKeys: Set<string>;
|
|
155
|
+
aliases: Map<string, Expr>;
|
|
156
|
+
withExprs: Map<string, Expr>;
|
|
157
|
+
withCache: Map<string, unknown>;
|
|
158
|
+
exec: Executor;
|
|
159
|
+
subCache: Map<Expr, unknown>;
|
|
160
|
+
outer?: Scope;
|
|
161
|
+
};
|
|
162
|
+
type Env = {
|
|
163
|
+
scope: Scope;
|
|
164
|
+
row: JRow;
|
|
165
|
+
group?: JRow[];
|
|
166
|
+
aliasCache: Map<string, unknown>;
|
|
167
|
+
evaluating: Set<string>;
|
|
168
|
+
lambda?: Map<string, unknown>;
|
|
169
|
+
aj?: Map<Expr, unknown>;
|
|
170
|
+
};
|
|
171
|
+
export declare function evalExpr(e: Expr, env: Env): unknown;
|
|
172
|
+
export declare function isKnownFunction(name: string): boolean;
|
|
173
|
+
export declare class Executor {
|
|
174
|
+
readonly catalog: Catalog;
|
|
175
|
+
readonly nowMs: number;
|
|
176
|
+
readonly validating: boolean;
|
|
177
|
+
rowsRead: number;
|
|
178
|
+
bytesRead: number;
|
|
179
|
+
/** `validating`: publish-time analysis — subqueries in expressions are analyzed even when no row reaches them. */
|
|
180
|
+
constructor(catalog: Catalog, nowMs: number, validating?: boolean);
|
|
181
|
+
/** Resolve a FROM name: CTEs in scope first, then the catalog. */
|
|
182
|
+
table(name: string, final: boolean, scope?: Scope): Relation;
|
|
183
|
+
run(q: Query, outer?: Scope): Relation;
|
|
184
|
+
/** Run and also report rows_before_limit (for the response envelope). */
|
|
185
|
+
runTop(q: Query): {
|
|
186
|
+
rel: Relation;
|
|
187
|
+
rowsBeforeLimit?: number;
|
|
188
|
+
};
|
|
189
|
+
private select;
|
|
190
|
+
/** The analyzer pass: every expression of the SELECT resolves (see "static checking"). */
|
|
191
|
+
private check;
|
|
192
|
+
private checkExpr;
|
|
193
|
+
private orderValue;
|
|
194
|
+
private defaultRow;
|
|
195
|
+
private relationOf;
|
|
196
|
+
private from;
|
|
197
|
+
private combine;
|
|
198
|
+
}
|
|
199
|
+
export type QueryResult = {
|
|
200
|
+
meta: ClickHouseColumn[];
|
|
201
|
+
data: Array<Record<string, unknown>>;
|
|
202
|
+
rows: number;
|
|
203
|
+
rowsBeforeLimitAtLeast?: number;
|
|
204
|
+
rowsRead: number;
|
|
205
|
+
bytesRead: number;
|
|
206
|
+
};
|
|
207
|
+
/** Execute a parsed query against a catalog and shape Tinybird's result envelope. */
|
|
208
|
+
export declare function executeSql(q: Query, catalog: Catalog, nowMs: number, opts?: {
|
|
209
|
+
validate?: boolean;
|
|
210
|
+
}): QueryResult;
|
|
211
|
+
/** Run a query to a Relation (for materialized views and node chaining). */
|
|
212
|
+
export declare function runSql(q: Query, catalog: Catalog, nowMs: number, opts?: {
|
|
213
|
+
validate?: boolean;
|
|
214
|
+
}): Relation;
|
|
215
|
+
/** Every table name a query reads (FROM / JOIN / IN-subqueries), excluding its own CTEs. */
|
|
216
|
+
export declare function usedTables(q: Query): string[];
|
|
217
|
+
/** The left-most table of the first SELECT — a materialized view's trigger table. */
|
|
218
|
+
export declare function primaryTable(q: Query): string | undefined;
|
|
219
|
+
export declare function queryStatistics(result: QueryResult): {
|
|
220
|
+
elapsed: number;
|
|
221
|
+
rows_read: number;
|
|
222
|
+
bytes_read: number;
|
|
223
|
+
};
|
|
224
|
+
/**
|
|
225
|
+
* Render a result in one of the modeled text formats (`.json` is handled by the caller):
|
|
226
|
+
* ClickHouse's JSONEachRow and CSV / CSVWithNames, every row (and the header) ending in `\n`.
|
|
227
|
+
*/
|
|
228
|
+
export declare function renderFormat(format: 'ndjson' | 'csv' | 'csvwithnames', result: QueryResult): string;
|
|
229
|
+
export type QueryPlan = Query;
|
|
230
|
+
/** Parse a SELECT and apply the checks ClickHouse makes before reading any data. */
|
|
231
|
+
export declare function parseQuery(sql: string): Query;
|
|
232
|
+
/** Run a query over ONE table's stored rows (any FROM name resolves to it). */
|
|
233
|
+
export declare function executeQuery(q: Query, columns: readonly ClickHouseColumn[], rows: ReadonlyArray<Record<string, unknown>>, nowMs?: number): QueryResult;
|