rust-kgdb 0.6.81 → 0.6.82
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 +281 -0
- package/examples/rpc-catalog-dprod-demo.js +339 -0
- package/examples/rpc-federation-sql-demo.js +273 -0
- package/examples/rpc-virtual-tables-demo.js +268 -0
- package/hypermind-agent.js +626 -0
- package/index.d.ts +304 -0
- package/index.js +9 -0
- package/package.json +1 -1
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ================================================================================
|
|
4
|
+
* RpcFederationProxy: Federated SQL Demo
|
|
5
|
+
* Cross-Database Queries via WASM RPC Proxy
|
|
6
|
+
* ================================================================================
|
|
7
|
+
*
|
|
8
|
+
* This demo showcases RpcFederationProxy from the rust-kgdb SDK:
|
|
9
|
+
* - Query across KGDB + Snowflake + BigQuery in single SQL statement
|
|
10
|
+
* - 7 Semantic UDFs (similar_to, neighbors, entity_type, etc.)
|
|
11
|
+
* - 9 Table Functions (graph_search, pagerank, vector_search, etc.)
|
|
12
|
+
* - Capability-based security with WasmSandbox
|
|
13
|
+
* - Full provenance tracking with audit log
|
|
14
|
+
*
|
|
15
|
+
* Architecture:
|
|
16
|
+
* - TypeScript SDK: Thin RPC proxy layer
|
|
17
|
+
* - Rust Core: Heavy lifting (DataFusion, Arrow, Vortex, HDRF partitioning)
|
|
18
|
+
*
|
|
19
|
+
* Run: node examples/rpc-federation-sql-demo.js
|
|
20
|
+
*
|
|
21
|
+
* @requires HyperFederate server running at http://localhost:30180
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
RpcFederationProxy,
|
|
26
|
+
FEDERATION_TOOLS,
|
|
27
|
+
GraphDB,
|
|
28
|
+
WasmSandbox,
|
|
29
|
+
ProofDAG
|
|
30
|
+
} = require('../index.js')
|
|
31
|
+
|
|
32
|
+
// ================================================================================
|
|
33
|
+
// DEMO: Federated SQL Queries
|
|
34
|
+
// ================================================================================
|
|
35
|
+
|
|
36
|
+
async function runDemo() {
|
|
37
|
+
console.log('╔══════════════════════════════════════════════════════════════════════╗')
|
|
38
|
+
console.log('║ RpcFederationProxy: Federated SQL Demo ║')
|
|
39
|
+
console.log('║ Cross-Database Queries via WASM RPC Proxy ║')
|
|
40
|
+
console.log('╚══════════════════════════════════════════════════════════════════════╝\n')
|
|
41
|
+
|
|
42
|
+
// Create RpcFederationProxy with custom config
|
|
43
|
+
const federation = new RpcFederationProxy({
|
|
44
|
+
endpoint: process.env.HYPERFEDERATE_URL || 'http://localhost:30180',
|
|
45
|
+
timeout: 30000,
|
|
46
|
+
identityId: 'demo-user-001',
|
|
47
|
+
// WasmSandbox provides capability-based security
|
|
48
|
+
sandbox: new WasmSandbox({
|
|
49
|
+
capabilities: ['ReadKG', 'ExecuteTool', 'Federation'],
|
|
50
|
+
fuelLimit: 100000
|
|
51
|
+
})
|
|
52
|
+
})
|
|
53
|
+
|
|
54
|
+
console.log(`Federation Endpoint: ${federation.endpoint}`)
|
|
55
|
+
console.log(`Session ID: ${federation.sessionId}`)
|
|
56
|
+
console.log(`Identity ID: ${federation.identityId}`)
|
|
57
|
+
console.log(`Initial Fuel: ${federation.getFuelRemaining()}`)
|
|
58
|
+
console.log()
|
|
59
|
+
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// 1. List available federation tools
|
|
62
|
+
// ============================================================================
|
|
63
|
+
console.log('1. Available Federation Tools (Category Theory: Typed Morphisms)')
|
|
64
|
+
console.log('═'.repeat(70))
|
|
65
|
+
for (const [name, tool] of Object.entries(FEDERATION_TOOLS)) {
|
|
66
|
+
console.log(` ${name}`)
|
|
67
|
+
console.log(` Input: ${tool.input}`)
|
|
68
|
+
console.log(` Output: ${tool.output}`)
|
|
69
|
+
console.log(` Domain: ${tool.domain}`)
|
|
70
|
+
console.log()
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// 2. Simple SQL query
|
|
75
|
+
// ============================================================================
|
|
76
|
+
console.log('2. Simple SQL Query')
|
|
77
|
+
console.log('═'.repeat(70))
|
|
78
|
+
try {
|
|
79
|
+
const simpleResult = await federation.query('SELECT 1 + 2 as result, NOW() as timestamp')
|
|
80
|
+
console.log(` Columns: ${simpleResult.columns.join(', ')}`)
|
|
81
|
+
console.log(` Rows: ${JSON.stringify(simpleResult.rows, null, 2)}`)
|
|
82
|
+
console.log(` Duration: ${simpleResult.duration}ms`)
|
|
83
|
+
console.log()
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.log(` [Skipped - Server not running: ${error.message}]`)
|
|
86
|
+
console.log()
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ============================================================================
|
|
90
|
+
// 3. KGDB + Snowflake Federation Query
|
|
91
|
+
// ============================================================================
|
|
92
|
+
console.log('3. KGDB + Snowflake Federation Query')
|
|
93
|
+
console.log('═'.repeat(70))
|
|
94
|
+
const kgSfQuery = `
|
|
95
|
+
-- Federation: KGDB (Knowledge Graph) + Snowflake (TPC-H)
|
|
96
|
+
WITH kg_entities AS (
|
|
97
|
+
SELECT * FROM graph_search('
|
|
98
|
+
PREFIX finance: <https://gonnect.ai/domains/finance#>
|
|
99
|
+
PREFIX tpch: <https://gonnect.ai/tpch#>
|
|
100
|
+
SELECT ?person ?custKey WHERE {
|
|
101
|
+
?person a finance:Person ;
|
|
102
|
+
tpch:custKey ?custKey .
|
|
103
|
+
} LIMIT 10
|
|
104
|
+
')
|
|
105
|
+
)
|
|
106
|
+
SELECT
|
|
107
|
+
kg.person AS kg_entity,
|
|
108
|
+
kg.custKey,
|
|
109
|
+
sf.C_NAME,
|
|
110
|
+
sf.C_ACCTBAL
|
|
111
|
+
FROM kg_entities kg
|
|
112
|
+
JOIN snowflake_tpch.CUSTOMER sf
|
|
113
|
+
ON CAST(kg.custKey AS INTEGER) = sf.C_CUSTKEY
|
|
114
|
+
LIMIT 10
|
|
115
|
+
`
|
|
116
|
+
console.log(` Query:\n${kgSfQuery.trim().split('\n').map(l => ' ' + l).join('\n')}`)
|
|
117
|
+
console.log()
|
|
118
|
+
try {
|
|
119
|
+
const result = await federation.query(kgSfQuery)
|
|
120
|
+
console.log(` Result: ${result.rowCount} rows in ${result.duration}ms`)
|
|
121
|
+
console.log(` Sources: ${result.metadata.sources?.join(', ')}`)
|
|
122
|
+
console.log()
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.log(` [Demo mode - Server not running]`)
|
|
125
|
+
console.log()
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ============================================================================
|
|
129
|
+
// 4. Three-Way Federation: KGDB + Snowflake + BigQuery
|
|
130
|
+
// ============================================================================
|
|
131
|
+
console.log('4. Three-Way Federation: KGDB + Snowflake + BigQuery')
|
|
132
|
+
console.log('═'.repeat(70))
|
|
133
|
+
const threeWayQuery = `
|
|
134
|
+
-- Three-way federation: KGDB + Snowflake + BigQuery
|
|
135
|
+
WITH
|
|
136
|
+
kg_risk AS (
|
|
137
|
+
SELECT * FROM graph_search('
|
|
138
|
+
PREFIX finance: <https://gonnect.ai/domains/finance#>
|
|
139
|
+
PREFIX tpch: <https://gonnect.ai/tpch#>
|
|
140
|
+
SELECT ?person ?custKey ?riskScore WHERE {
|
|
141
|
+
?risk finance:assessedFor ?person ;
|
|
142
|
+
finance:riskScore ?riskScore .
|
|
143
|
+
?person tpch:custKey ?custKey .
|
|
144
|
+
FILTER(?riskScore > 0.7)
|
|
145
|
+
} LIMIT 5
|
|
146
|
+
')
|
|
147
|
+
),
|
|
148
|
+
sf_cust AS (
|
|
149
|
+
SELECT C_CUSTKEY, C_NAME, C_ACCTBAL
|
|
150
|
+
FROM snowflake_tpch.CUSTOMER
|
|
151
|
+
LIMIT 100
|
|
152
|
+
)
|
|
153
|
+
SELECT
|
|
154
|
+
kg.person AS kg_entity,
|
|
155
|
+
kg.riskScore,
|
|
156
|
+
sf.C_NAME,
|
|
157
|
+
sf.C_ACCTBAL,
|
|
158
|
+
bq.name AS popular_name,
|
|
159
|
+
bq.number AS birth_count
|
|
160
|
+
FROM kg_risk kg
|
|
161
|
+
JOIN sf_cust sf ON CAST(kg.custKey AS INTEGER) = sf.C_CUSTKEY
|
|
162
|
+
LEFT JOIN bigquery_public.usa_1910_current bq
|
|
163
|
+
ON LOWER(SPLIT_PART(sf.C_NAME, ' ', 1)) = LOWER(bq.name)
|
|
164
|
+
WHERE bq.year = 2000
|
|
165
|
+
LIMIT 10
|
|
166
|
+
`
|
|
167
|
+
console.log(` Query: Three-way federation across KGDB + Snowflake + BigQuery`)
|
|
168
|
+
console.log()
|
|
169
|
+
|
|
170
|
+
// ============================================================================
|
|
171
|
+
// 5. Semantic UDF Examples (7 AI-Powered Functions)
|
|
172
|
+
// ============================================================================
|
|
173
|
+
console.log('5. Semantic UDFs (7 AI-Powered Functions)')
|
|
174
|
+
console.log('═'.repeat(70))
|
|
175
|
+
const udfs = [
|
|
176
|
+
{ name: 'similar_to', example: "similar_to('<http://ex.org/Entity1>', 0.7)" },
|
|
177
|
+
{ name: 'text_search', example: "text_search('high risk fraud', 5)" },
|
|
178
|
+
{ name: 'neighbors', example: "neighbors('<http://ex.org/Entity1>', 2)" },
|
|
179
|
+
{ name: 'graph_pattern', example: "graph_pattern('<http://ex.org/Entity1>', NULL, NULL)" },
|
|
180
|
+
{ name: 'sparql_query', example: "sparql_query('SELECT ?s WHERE { ?s a <http://ex.org/Person> }')" },
|
|
181
|
+
{ name: 'entity_type', example: "entity_type('<http://ex.org/Entity1>')" },
|
|
182
|
+
{ name: 'entity_properties', example: "entity_properties('<http://ex.org/Entity1>')" }
|
|
183
|
+
]
|
|
184
|
+
for (const udf of udfs) {
|
|
185
|
+
console.log(` ${udf.name}`)
|
|
186
|
+
console.log(` Example: SELECT ${udf.example}`)
|
|
187
|
+
console.log()
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ============================================================================
|
|
191
|
+
// 6. Table Functions (9 Graph Analytics)
|
|
192
|
+
// ============================================================================
|
|
193
|
+
console.log('6. Table Functions (9 Graph Analytics)')
|
|
194
|
+
console.log('═'.repeat(70))
|
|
195
|
+
const tableFunctions = [
|
|
196
|
+
{ name: 'graph_search', desc: 'SPARQL → SQL bridge' },
|
|
197
|
+
{ name: 'vector_search', desc: 'Semantic similarity search' },
|
|
198
|
+
{ name: 'pagerank', desc: 'PageRank centrality' },
|
|
199
|
+
{ name: 'connected_components', desc: 'Community detection' },
|
|
200
|
+
{ name: 'shortest_paths', desc: 'Path finding' },
|
|
201
|
+
{ name: 'triangle_count', desc: 'Graph density measure' },
|
|
202
|
+
{ name: 'label_propagation', desc: 'Community detection' },
|
|
203
|
+
{ name: 'datalog_reason', desc: 'Datalog inference' },
|
|
204
|
+
{ name: 'motif_search', desc: 'Graph pattern matching' }
|
|
205
|
+
]
|
|
206
|
+
for (const fn of tableFunctions) {
|
|
207
|
+
console.log(` ${fn.name.padEnd(25)} - ${fn.desc}`)
|
|
208
|
+
}
|
|
209
|
+
console.log()
|
|
210
|
+
|
|
211
|
+
// ============================================================================
|
|
212
|
+
// 7. Audit Log (Provenance Tracking)
|
|
213
|
+
// ============================================================================
|
|
214
|
+
console.log('7. Audit Log (Provenance Tracking - Proof Theory)')
|
|
215
|
+
console.log('═'.repeat(70))
|
|
216
|
+
const auditLog = federation.getAuditLog()
|
|
217
|
+
console.log(` Total entries: ${auditLog.length}`)
|
|
218
|
+
for (const entry of auditLog.slice(0, 3)) {
|
|
219
|
+
console.log(` - Action: ${entry.action}`)
|
|
220
|
+
console.log(` Duration: ${entry.duration}ms`)
|
|
221
|
+
console.log(` Rows: ${entry.rows}`)
|
|
222
|
+
console.log(` Timestamp: ${entry.timestamp}`)
|
|
223
|
+
console.log()
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// ============================================================================
|
|
227
|
+
// 8. ProofDAG with Federation Evidence
|
|
228
|
+
// ============================================================================
|
|
229
|
+
console.log('8. ProofDAG with Federation Evidence')
|
|
230
|
+
console.log('═'.repeat(70))
|
|
231
|
+
const proof = new ProofDAG('High-risk customers identified across 3 data sources')
|
|
232
|
+
|
|
233
|
+
// Add federation evidence to the proof
|
|
234
|
+
const fedNode = proof.addFederationEvidence(
|
|
235
|
+
proof.rootId,
|
|
236
|
+
threeWayQuery,
|
|
237
|
+
['kgdb', 'snowflake', 'bigquery'],
|
|
238
|
+
42, // rowCount
|
|
239
|
+
890, // duration
|
|
240
|
+
{ planHash: 'abc123', cached: false }
|
|
241
|
+
)
|
|
242
|
+
console.log(` Root claim: ${proof.rootClaim}`)
|
|
243
|
+
console.log(` Proof hash: ${proof.computeHash()}`)
|
|
244
|
+
console.log(` Verification: ${JSON.stringify(proof.verify())}`)
|
|
245
|
+
console.log()
|
|
246
|
+
|
|
247
|
+
// ============================================================================
|
|
248
|
+
// Summary
|
|
249
|
+
// ============================================================================
|
|
250
|
+
console.log('╔══════════════════════════════════════════════════════════════════════╗')
|
|
251
|
+
console.log('║ Demo Complete! ║')
|
|
252
|
+
console.log('╚══════════════════════════════════════════════════════════════════════╝')
|
|
253
|
+
console.log(`
|
|
254
|
+
Key Capabilities Demonstrated:
|
|
255
|
+
- RpcFederationProxy: Thin SDK proxy to Rust HyperFederate server
|
|
256
|
+
- Cross-Database SQL: KGDB + Snowflake + BigQuery in single query
|
|
257
|
+
- 7 Semantic UDFs: AI-powered functions in SQL context
|
|
258
|
+
- 9 Table Functions: Graph analytics via SQL
|
|
259
|
+
- WasmSandbox: Capability-based security with fuel metering
|
|
260
|
+
- ProofDAG: Full provenance tracking (W3C PROV compatible)
|
|
261
|
+
|
|
262
|
+
Architecture Principle:
|
|
263
|
+
- Heavy lifting in Rust core (DataFusion, Arrow, Vortex, HDRF)
|
|
264
|
+
- TypeScript SDK is thin RPC proxy layer
|
|
265
|
+
- Category Theory: Tools as typed morphisms (Input → Output)
|
|
266
|
+
- Proof Theory: Every answer has verifiable reasoning chain
|
|
267
|
+
|
|
268
|
+
Fuel Remaining: ${federation.getFuelRemaining()}
|
|
269
|
+
`)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Run the demo
|
|
273
|
+
runDemo().catch(console.error)
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ================================================================================
|
|
4
|
+
* RpcFederationProxy: Virtual Tables Demo
|
|
5
|
+
* Session-Bound Query Result Materialization
|
|
6
|
+
* ================================================================================
|
|
7
|
+
*
|
|
8
|
+
* Virtual Tables in HyperFederate:
|
|
9
|
+
* - Session-bound materialization of federation query results
|
|
10
|
+
* - Stored as RDF triples in KGDB (self-describing)
|
|
11
|
+
* - Access control via shared_with and shared_with_groups
|
|
12
|
+
* - Refresh policies: on_demand, ttl, on_source_change
|
|
13
|
+
* - No ETL required - real-time query materialization
|
|
14
|
+
*
|
|
15
|
+
* Architecture:
|
|
16
|
+
* - Heavy lifting in Rust core (DataFusion, Arrow, KGDB storage)
|
|
17
|
+
* - TypeScript SDK provides thin RPC proxy layer
|
|
18
|
+
*
|
|
19
|
+
* Run: node examples/rpc-virtual-tables-demo.js
|
|
20
|
+
*
|
|
21
|
+
* @requires HyperFederate server running at http://localhost:30180
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const {
|
|
25
|
+
RpcFederationProxy,
|
|
26
|
+
WasmSandbox,
|
|
27
|
+
ProofDAG
|
|
28
|
+
} = require('../index.js')
|
|
29
|
+
|
|
30
|
+
// ================================================================================
|
|
31
|
+
// DEMO: Virtual Tables
|
|
32
|
+
// ================================================================================
|
|
33
|
+
|
|
34
|
+
async function runDemo() {
|
|
35
|
+
console.log('╔══════════════════════════════════════════════════════════════════════╗')
|
|
36
|
+
console.log('║ RpcFederationProxy: Virtual Tables Demo ║')
|
|
37
|
+
console.log('║ Session-Bound Query Result Materialization ║')
|
|
38
|
+
console.log('╚══════════════════════════════════════════════════════════════════════╝\n')
|
|
39
|
+
|
|
40
|
+
// Create RpcFederationProxy
|
|
41
|
+
const federation = new RpcFederationProxy({
|
|
42
|
+
endpoint: process.env.HYPERFEDERATE_URL || 'http://localhost:30180',
|
|
43
|
+
identityId: 'risk-analyst-001'
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
console.log(`Federation Endpoint: ${federation.endpoint}`)
|
|
47
|
+
console.log(`Session ID: ${federation.sessionId}`)
|
|
48
|
+
console.log(`Identity ID: ${federation.identityId}`)
|
|
49
|
+
console.log()
|
|
50
|
+
|
|
51
|
+
// ============================================================================
|
|
52
|
+
// 1. Create Virtual Table from Federation Query
|
|
53
|
+
// ============================================================================
|
|
54
|
+
console.log('1. Create Virtual Table from Federation Query')
|
|
55
|
+
console.log('═'.repeat(70))
|
|
56
|
+
|
|
57
|
+
const createVtQuery = `
|
|
58
|
+
-- High-risk customers: KGDB risk scores + Snowflake account data
|
|
59
|
+
SELECT
|
|
60
|
+
kg.person AS kg_entity,
|
|
61
|
+
kg.riskScore AS risk_level,
|
|
62
|
+
entity_type(kg.person) AS entity_types,
|
|
63
|
+
sf.C_NAME AS customer_name,
|
|
64
|
+
sf.C_ACCTBAL AS account_balance,
|
|
65
|
+
sf.C_MKTSEGMENT AS market_segment
|
|
66
|
+
FROM graph_search('
|
|
67
|
+
PREFIX finance: <https://gonnect.ai/domains/finance#>
|
|
68
|
+
PREFIX tpch: <https://gonnect.ai/tpch#>
|
|
69
|
+
SELECT ?person ?riskScore ?custKey WHERE {
|
|
70
|
+
?risk finance:assessedFor ?person ;
|
|
71
|
+
finance:riskScore ?riskScore .
|
|
72
|
+
?person tpch:custKey ?custKey .
|
|
73
|
+
FILTER(?riskScore > 0.7)
|
|
74
|
+
}
|
|
75
|
+
') kg
|
|
76
|
+
JOIN snowflake_tpch.CUSTOMER sf
|
|
77
|
+
ON CAST(kg.custKey AS INTEGER) = sf.C_CUSTKEY
|
|
78
|
+
WHERE sf.C_ACCTBAL > 50000
|
|
79
|
+
`
|
|
80
|
+
|
|
81
|
+
console.log(' SQL Query:')
|
|
82
|
+
console.log(createVtQuery.trim().split('\n').map(l => ' ' + l).join('\n'))
|
|
83
|
+
console.log()
|
|
84
|
+
|
|
85
|
+
try {
|
|
86
|
+
const vt = await federation.createVirtualTable('high_risk_customers', createVtQuery, {
|
|
87
|
+
refreshPolicy: 'on_demand',
|
|
88
|
+
ttlSeconds: 3600,
|
|
89
|
+
sharedWith: ['risk-analyst-002', 'compliance-officer-001'],
|
|
90
|
+
sharedWithGroups: ['team-risk-analytics', 'team-compliance']
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
console.log(' Virtual Table Created:')
|
|
94
|
+
console.log(` ID: ${vt.id}`)
|
|
95
|
+
console.log(` Name: ${vt.name}`)
|
|
96
|
+
console.log(` URI: ${vt.uri}`)
|
|
97
|
+
console.log(` Columns: ${vt.columns.join(', ')}`)
|
|
98
|
+
console.log(` Row Count: ${vt.rowCount}`)
|
|
99
|
+
console.log(` Refresh Policy: ${vt.refreshPolicy}`)
|
|
100
|
+
console.log(` Created At: ${vt.createdAt}`)
|
|
101
|
+
console.log()
|
|
102
|
+
} catch (error) {
|
|
103
|
+
console.log(` [Demo mode - Server not running]`)
|
|
104
|
+
console.log(` Virtual table would be created with:`)
|
|
105
|
+
console.log(` Name: high_risk_customers`)
|
|
106
|
+
console.log(` Refresh Policy: on_demand`)
|
|
107
|
+
console.log(` TTL: 3600 seconds`)
|
|
108
|
+
console.log(` Shared With: risk-analyst-002, compliance-officer-001`)
|
|
109
|
+
console.log(` Shared Groups: team-risk-analytics, team-compliance`)
|
|
110
|
+
console.log()
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// ============================================================================
|
|
114
|
+
// 2. Query Virtual Table (No Re-execution)
|
|
115
|
+
// ============================================================================
|
|
116
|
+
console.log('2. Query Virtual Table (Materialized Results)')
|
|
117
|
+
console.log('═'.repeat(70))
|
|
118
|
+
console.log(' Virtual tables are materialized - no query re-execution needed.')
|
|
119
|
+
console.log()
|
|
120
|
+
console.log(' Query: SELECT * FROM virtual.high_risk_customers WHERE account_balance > 100000')
|
|
121
|
+
console.log()
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
const result = await federation.queryVirtualTable('high_risk_customers', 'account_balance > 100000')
|
|
125
|
+
console.log(` Result: ${result.rowCount} rows in ${result.duration}ms`)
|
|
126
|
+
console.log(` (Materialized data, not re-executed)`)
|
|
127
|
+
console.log()
|
|
128
|
+
} catch (error) {
|
|
129
|
+
console.log(` [Demo mode - Would query materialized virtual table]`)
|
|
130
|
+
console.log()
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// 3. Virtual Table Use Cases
|
|
135
|
+
// ============================================================================
|
|
136
|
+
console.log('3. Virtual Table Use Cases')
|
|
137
|
+
console.log('═'.repeat(70))
|
|
138
|
+
const useCases = [
|
|
139
|
+
{
|
|
140
|
+
name: 'Risk Dashboard',
|
|
141
|
+
query: `CREATE VIRTUAL TABLE risk_dashboard AS
|
|
142
|
+
SELECT entity, risk_score, neighbors(entity, 1) AS network
|
|
143
|
+
FROM high_risk_customers`,
|
|
144
|
+
refresh: 'ttl (5 min)',
|
|
145
|
+
shared: 'team-risk-analytics'
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
name: 'Compliance Audit',
|
|
149
|
+
query: `CREATE VIRTUAL TABLE compliance_audit AS
|
|
150
|
+
SELECT entity, risk_score, entity_properties(entity) AS all_props
|
|
151
|
+
FROM high_risk_customers WHERE risk_score > 0.9`,
|
|
152
|
+
refresh: 'on_source_change',
|
|
153
|
+
shared: 'compliance-officers'
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'Customer 360',
|
|
157
|
+
query: `CREATE VIRTUAL TABLE customer_360 AS
|
|
158
|
+
SELECT kg.*, sf.*, bq.name_popularity
|
|
159
|
+
FROM graph_search(...) kg
|
|
160
|
+
JOIN snowflake.CUSTOMER sf ON ...
|
|
161
|
+
LEFT JOIN bigquery.usa_names bq ON ...`,
|
|
162
|
+
refresh: 'on_demand',
|
|
163
|
+
shared: 'team-customer-success'
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
for (const useCase of useCases) {
|
|
168
|
+
console.log(` ${useCase.name}`)
|
|
169
|
+
console.log(` Refresh: ${useCase.refresh}`)
|
|
170
|
+
console.log(` Shared With: ${useCase.shared}`)
|
|
171
|
+
console.log()
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ============================================================================
|
|
175
|
+
// 4. Access Control Model
|
|
176
|
+
// ============================================================================
|
|
177
|
+
console.log('4. Access Control Model')
|
|
178
|
+
console.log('═'.repeat(70))
|
|
179
|
+
console.log(`
|
|
180
|
+
Virtual tables support fine-grained access control:
|
|
181
|
+
|
|
182
|
+
┌─────────────────────────────────────────────────────────────────────┐
|
|
183
|
+
│ Virtual Table: high_risk_customers │
|
|
184
|
+
│ Owner: risk-analyst-001 (creator) │
|
|
185
|
+
├─────────────────────────────────────────────────────────────────────┤
|
|
186
|
+
│ shared_with (individuals): │
|
|
187
|
+
│ - risk-analyst-002 [Full access] │
|
|
188
|
+
│ - compliance-officer-001 [Full access] │
|
|
189
|
+
│ │
|
|
190
|
+
│ shared_with_groups (teams): │
|
|
191
|
+
│ - team-risk-analytics [All members have access] │
|
|
192
|
+
│ - team-compliance [All members have access] │
|
|
193
|
+
└─────────────────────────────────────────────────────────────────────┘
|
|
194
|
+
|
|
195
|
+
Access check: has_access(identity_id, groups) → boolean
|
|
196
|
+
`)
|
|
197
|
+
|
|
198
|
+
// ============================================================================
|
|
199
|
+
// 5. RDF Storage (Self-Describing)
|
|
200
|
+
// ============================================================================
|
|
201
|
+
console.log('5. Virtual Table RDF Storage (Self-Describing)')
|
|
202
|
+
console.log('═'.repeat(70))
|
|
203
|
+
console.log(`
|
|
204
|
+
Virtual tables are stored as RDF triples in KGDB:
|
|
205
|
+
|
|
206
|
+
<urn:hyperfederate:vt:${federation.sessionId}:high_risk_customers>
|
|
207
|
+
a hf:VirtualTable ;
|
|
208
|
+
hf:name "high_risk_customers" ;
|
|
209
|
+
hf:sessionId "${federation.sessionId}" ;
|
|
210
|
+
hf:ownerId "${federation.identityId}" ;
|
|
211
|
+
hf:query "SELECT kg.person, kg.riskScore..." ;
|
|
212
|
+
hf:refreshPolicy "on_demand" ;
|
|
213
|
+
hf:rowCount "42"^^xsd:integer ;
|
|
214
|
+
hf:createdAt "2024-12-21T12:00:00Z"^^xsd:dateTime ;
|
|
215
|
+
hf:sourceLineage "kgdb", "snowflake" ;
|
|
216
|
+
hf:sharedWith "risk-analyst-002", "compliance-officer-001" ;
|
|
217
|
+
hf:sharedWithGroups "team-risk-analytics", "team-compliance" .
|
|
218
|
+
|
|
219
|
+
This makes virtual tables queryable via SPARQL!
|
|
220
|
+
`)
|
|
221
|
+
|
|
222
|
+
// ============================================================================
|
|
223
|
+
// 6. ProofDAG Integration
|
|
224
|
+
// ============================================================================
|
|
225
|
+
console.log('6. ProofDAG Integration (Provenance Tracking)')
|
|
226
|
+
console.log('═'.repeat(70))
|
|
227
|
+
|
|
228
|
+
const proof = new ProofDAG('Risk analysis for high-value customers')
|
|
229
|
+
|
|
230
|
+
// Add virtual table creation as evidence
|
|
231
|
+
const vtNode = proof.addVirtualTableEvidence(
|
|
232
|
+
proof.rootId,
|
|
233
|
+
'high_risk_customers',
|
|
234
|
+
createVtQuery,
|
|
235
|
+
42 // rowCount
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
console.log(` Root claim: ${proof.rootClaim}`)
|
|
239
|
+
console.log(` Evidence type: virtual_table`)
|
|
240
|
+
console.log(` Proof hash: ${proof.computeHash()}`)
|
|
241
|
+
console.log()
|
|
242
|
+
|
|
243
|
+
// ============================================================================
|
|
244
|
+
// Summary
|
|
245
|
+
// ============================================================================
|
|
246
|
+
console.log('╔══════════════════════════════════════════════════════════════════════╗')
|
|
247
|
+
console.log('║ Demo Complete! ║')
|
|
248
|
+
console.log('╚══════════════════════════════════════════════════════════════════════╝')
|
|
249
|
+
console.log(`
|
|
250
|
+
Virtual Table Benefits:
|
|
251
|
+
- No ETL Pipeline: Real-time query materialization
|
|
252
|
+
- Session Isolation: Each user sees only their tables
|
|
253
|
+
- Access Control: Fine-grained sharing via identities/groups
|
|
254
|
+
- Self-Describing: Stored as RDF, queryable via SPARQL
|
|
255
|
+
- Refresh Policies: on_demand, ttl, on_source_change
|
|
256
|
+
- Provenance: Full lineage tracking via ProofDAG
|
|
257
|
+
|
|
258
|
+
Architecture Principle:
|
|
259
|
+
- Materialization logic in Rust core (DataFusion + KGDB)
|
|
260
|
+
- TypeScript SDK provides thin RPC proxy layer
|
|
261
|
+
- Heavy computation happens server-side
|
|
262
|
+
|
|
263
|
+
Audit Log Entries: ${federation.getAuditLog().length}
|
|
264
|
+
`)
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Run the demo
|
|
268
|
+
runDemo().catch(console.error)
|