Skip to content

Commit a76c2b0

Browse files
committed
Bump deps, parser fixes, example UI & SDK docs
Update dependency versions (uuid -> 1.22.0, libc -> 0.2.183) and remove chrono/getrandom from the wasm feature set. Enhance SQL parser to recognize CURRENT_USER / CURRENT_ROLE keywords and rewrite them to KDB_CURRENT_*() for DataFusion (adds regexes and a unit test). Improve example apps: add vite env types, compute stable sort keys and sort/cap rows for chat and activity examples to ensure deterministic ordering. Revise link/ README and Dart SDK README to reflect current SDK shape, usage, and init/connect patterns; adjust crate feature lists. Misc: update related generated SDK artifacts and native libs.
1 parent 6e5738f commit a76c2b0

27 files changed

Lines changed: 818 additions & 1203 deletions

File tree

Cargo.lock

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ actix-files = "0.6.10"
8787
actix-multipart = "0.7"
8888

8989
# UUID generation
90-
uuid = { version = "1.21.0", features = ["v4", "v7", "serde"] }
90+
uuid = { version = "1.22.0", features = ["v4", "v7", "serde"] }
9191

9292
# NanoID generation (21-char URL-safe unique IDs)
9393
nanoid = "0.4.0"
@@ -175,9 +175,8 @@ ntest = "0.9.5"
175175
wasm-bindgen = { version = "0.2.114" }
176176
wasm-bindgen-futures = { version = "0.4.64" }
177177
js-sys = { version = "0.3.91" }
178-
libc = "0.2.182"
178+
libc = "0.2.183"
179179
web-sys = { version = "0.3.91" }
180-
getrandom = { version = "0.2.15" }
181180
tsify-next = { version = "0.5", default-features = false, features = ["js"] }
182181
serde-wasm-bindgen = "0.6"
183182
flate2 = "1.1.9"

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ const threadSql = `
7272
SELECT id, role, content, created_at
7373
FROM chat.messages
7474
WHERE thread_id = 'thread_42'
75-
ORDER BY created_at ASC
7675
`;
7776

7877
await client.query(`

backend/crates/kalamdb-sql/src/parser/utils.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ static CURRENT_ROLE_CALL_RE: Lazy<Regex> =
2020
Lazy::new(|| Regex::new(r"(?i)\bCURRENT_ROLE\s*\(\s*\)").expect("valid regex"));
2121
static CURRENT_USER_ID_CALL_RE: Lazy<Regex> =
2222
Lazy::new(|| Regex::new(r"(?i)\bCURRENT_USER_ID\s*\(\s*\)").expect("valid regex"));
23+
static CURRENT_USER_KEYWORD_RE: Lazy<Regex> =
24+
Lazy::new(|| {
25+
Regex::new(r"(?i)(^|[^A-Za-z0-9_])(CURRENT_USER)([^A-Za-z0-9_(]|$)")
26+
.expect("valid regex")
27+
});
28+
static CURRENT_ROLE_KEYWORD_RE: Lazy<Regex> =
29+
Lazy::new(|| {
30+
Regex::new(r"(?i)(^|[^A-Za-z0-9_])(CURRENT_ROLE)([^A-Za-z0-9_(]|$)")
31+
.expect("valid regex")
32+
});
2333

2434
/// Default sqlparser options used across KalamDB
2535
pub fn parser_options() -> ParserOptions {
@@ -43,8 +53,10 @@ pub fn normalize_context_keyword_calls_for_sqlparser(sql: &str) -> String {
4353
pub fn rewrite_context_functions_for_datafusion(sql: &str) -> String {
4454
let sql = CURRENT_USER_ID_CALL_RE.replace_all(sql, "KDB_CURRENT_USER_ID()");
4555
let sql = CURRENT_USER_CALL_RE.replace_all(&sql, "KDB_CURRENT_USER()");
46-
CURRENT_ROLE_CALL_RE
47-
.replace_all(&sql, "KDB_CURRENT_ROLE()")
56+
let sql = CURRENT_ROLE_CALL_RE.replace_all(&sql, "KDB_CURRENT_ROLE()");
57+
let sql = CURRENT_USER_KEYWORD_RE.replace_all(&sql, "${1}KDB_CURRENT_USER()${3}");
58+
CURRENT_ROLE_KEYWORD_RE
59+
.replace_all(&sql, "${1}KDB_CURRENT_ROLE()${3}")
4860
.into_owned()
4961
}
5062

@@ -494,4 +506,15 @@ mod tests {
494506
"SELECT KDB_CURRENT_USER(), KDB_CURRENT_USER_ID(), KDB_CURRENT_ROLE()"
495507
);
496508
}
509+
510+
#[test]
511+
fn test_rewrite_context_keywords_for_datafusion() {
512+
let rewritten = rewrite_context_functions_for_datafusion(
513+
"SELECT CURRENT_USER AS username, CURRENT_ROLE AS role",
514+
);
515+
assert_eq!(
516+
rewritten,
517+
"SELECT KDB_CURRENT_USER() AS username, KDB_CURRENT_ROLE() AS role"
518+
);
519+
}
497520
}

examples/chat-with-ai/src/App.tsx

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type ChatMessage = {
88
author: string;
99
content: string;
1010
createdAt: string;
11+
sortKey: number;
1112
};
1213

1314
type AgentEvent = {
@@ -17,6 +18,7 @@ type AgentEvent = {
1718
preview: string;
1819
message: string;
1920
createdAt: string;
21+
sortKey: number;
2022
};
2123

2224
type LiveDraft = {
@@ -35,13 +37,11 @@ const CHAT_SQL = [
3537
'SELECT id, role, author, content, created_at',
3638
'FROM chat_demo.messages',
3739
`WHERE room = '${ROOM_SQL}'`,
38-
'ORDER BY created_at ASC, id ASC',
3940
].join(' ');
4041
const EVENTS_SQL = [
4142
'SELECT id, response_id, stage, preview, message, created_at',
4243
'FROM chat_demo.agent_events',
4344
`WHERE room = '${ROOM_SQL}'`,
44-
'ORDER BY created_at ASC, id ASC',
4545
].join(' ');
4646

4747
function createAuthedClient() {
@@ -81,26 +81,38 @@ function formatTimestamp(rawValue: string): string {
8181
}
8282

8383
function toMessage(row: RowData): ChatMessage {
84+
const sortKey = row['created_at']?.asDate()?.getTime() ?? row['_seq']?.asSeqId()?.timestampMillis() ?? 0;
8485
return {
8586
id: text(row, 'id'),
8687
role: text(row, 'role'),
8788
author: text(row, 'author'),
8889
content: text(row, 'content'),
8990
createdAt: formatTimestamp(text(row, 'created_at')),
91+
sortKey,
9092
};
9193
}
9294

9395
function toAgentEvent(row: RowData): AgentEvent {
96+
const sortKey = row['created_at']?.asDate()?.getTime() ?? row['_seq']?.asSeqId()?.timestampMillis() ?? 0;
9497
return {
9598
id: text(row, 'id'),
9699
responseId: text(row, 'response_id'),
97100
stage: text(row, 'stage'),
98101
preview: text(row, 'preview'),
99102
message: text(row, 'message'),
100103
createdAt: formatTimestamp(text(row, 'created_at')),
104+
sortKey,
101105
};
102106
}
103107

108+
function sortMessages(rows: ChatMessage[]): ChatMessage[] {
109+
return [...rows].sort((left, right) => left.sortKey - right.sortKey || left.id.localeCompare(right.id));
110+
}
111+
112+
function sortEvents(rows: AgentEvent[]): AgentEvent[] {
113+
return [...rows].sort((left, right) => left.sortKey - right.sortKey || left.id.localeCompare(right.id));
114+
}
115+
104116
function deriveLiveDraft(events: AgentEvent[]): LiveDraft | null {
105117
let activeEvent: AgentEvent | null = null;
106118

@@ -161,7 +173,7 @@ export function App() {
161173
CHAT_SQL,
162174
(nextMessages) => {
163175
if (active) {
164-
setMessages(nextMessages);
176+
setMessages(sortMessages(nextMessages));
165177
}
166178
},
167179
{
@@ -182,7 +194,7 @@ export function App() {
182194
EVENTS_SQL,
183195
(nextEvents) => {
184196
if (active) {
185-
setEvents(nextEvents);
197+
setEvents(sortEvents(nextEvents));
186198
}
187199
},
188200
{
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/// <reference types="vite/client" />
2+
3+
interface ImportMetaEnv {
4+
readonly VITE_CHAT_ROOM: string
5+
readonly VITE_KALAMDB_URL: string
6+
readonly VITE_KALAMDB_USERNAME: string
7+
readonly VITE_KALAMDB_PASSWORD: string
8+
}
9+
10+
interface ImportMeta {
11+
readonly env: ImportMetaEnv
12+
}

examples/simple-typescript/src/App.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ type ActivityItem = {
1818
const FEED_SQL = [
1919
'SELECT id, service, level, actor, message, created_at',
2020
'FROM demo.activity_feed',
21-
'ORDER BY created_at DESC',
22-
'LIMIT 12',
2321
].join(' ');
2422

2523
const client = createClient({
@@ -46,6 +44,16 @@ function toActivity(row: RowData): ActivityItem {
4644
};
4745
}
4846

47+
function readTimestamp(row: RowData, key: string): number {
48+
return row[key]?.asDate()?.getTime() ?? row[key]?.asInt() ?? 0;
49+
}
50+
51+
function sortRecentActivity(rows: RowData[]): RowData[] {
52+
return [...rows]
53+
.sort((left, right) => readTimestamp(right, 'created_at') - readTimestamp(left, 'created_at'))
54+
.slice(0, 12);
55+
}
56+
4957
export function App() {
5058
const [items, setItems] = useState<ActivityItem[]>([]);
5159
const [status, setStatus] = useState<'loading' | 'live' | 'error'>('loading');
@@ -76,7 +84,7 @@ export function App() {
7684
return;
7785
}
7886

79-
setItems(rows.map(toActivity));
87+
setItems(sortRecentActivity(rows).map(toActivity));
8088
setStatus('live');
8189
},
8290
{

link/Cargo.toml

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,6 @@ http-body-util = { workspace = true }
3434
# HTTP Basic Auth encoding
3535
base64 = { workspace = true }
3636

37-
# Date/time handling for timestamp formatting
38-
# Minimal features: no serde, no iana-time-zone, no oldtime (saves ~0.3MB)
39-
chrono = { version = "0.4.44", default-features = false, features = ["clock", "std"] }
40-
41-
# Random number generation for WASM
42-
getrandom = { version = "0.2", optional = true, features = ["js"] }
43-
4437
# Futures utilities
4538
futures-util = { workspace = true, default-features = false }
4639

@@ -92,7 +85,7 @@ default = ["tokio-runtime"]
9285
tokio-runtime = ["tokio", "reqwest", "tokio-tungstenite"]
9386
# Optional HTTP/2 support via reqwest (adds ~1.7MB h2 crate)
9487
http2 = ["reqwest/http2"]
95-
wasm = ["wasm-bindgen", "wasm-bindgen-futures", "js-sys", "web-sys", "getrandom", "tsify-next", "serde-wasm-bindgen", "chrono/wasmbind"]
88+
wasm = ["wasm-bindgen", "wasm-bindgen-futures", "js-sys", "web-sys", "tsify-next", "serde-wasm-bindgen"]
9689
# End-to-end tests require a running KalamDB server
9790
e2e-tests = []
9891

0 commit comments

Comments
 (0)