agentdb 1.5.8 → 1.6.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 +11 -11
- package/dist/agentdb.min.js +4 -4
- package/dist/cli/agentdb-cli.d.ts +29 -0
- package/dist/cli/agentdb-cli.d.ts.map +1 -1
- package/dist/cli/agentdb-cli.js +1009 -34
- package/dist/cli/agentdb-cli.js.map +1 -1
- package/dist/controllers/ContextSynthesizer.d.ts +65 -0
- package/dist/controllers/ContextSynthesizer.d.ts.map +1 -0
- package/dist/controllers/ContextSynthesizer.js +208 -0
- package/dist/controllers/ContextSynthesizer.js.map +1 -0
- package/dist/controllers/MMRDiversityRanker.d.ts +50 -0
- package/dist/controllers/MMRDiversityRanker.d.ts.map +1 -0
- package/dist/controllers/MMRDiversityRanker.js +130 -0
- package/dist/controllers/MMRDiversityRanker.js.map +1 -0
- package/dist/controllers/MetadataFilter.d.ts +70 -0
- package/dist/controllers/MetadataFilter.d.ts.map +1 -0
- package/dist/controllers/MetadataFilter.js +243 -0
- package/dist/controllers/MetadataFilter.js.map +1 -0
- package/dist/controllers/QUICClient.d.ts +109 -0
- package/dist/controllers/QUICClient.d.ts.map +1 -0
- package/dist/controllers/QUICClient.js +299 -0
- package/dist/controllers/QUICClient.js.map +1 -0
- package/dist/controllers/QUICServer.d.ts +121 -0
- package/dist/controllers/QUICServer.d.ts.map +1 -0
- package/dist/controllers/QUICServer.js +383 -0
- package/dist/controllers/QUICServer.js.map +1 -0
- package/dist/controllers/SyncCoordinator.d.ts +120 -0
- package/dist/controllers/SyncCoordinator.d.ts.map +1 -0
- package/dist/controllers/SyncCoordinator.js +441 -0
- package/dist/controllers/SyncCoordinator.js.map +1 -0
- package/dist/controllers/WASMVectorSearch.d.ts.map +1 -1
- package/dist/controllers/WASMVectorSearch.js +10 -2
- package/dist/controllers/WASMVectorSearch.js.map +1 -1
- package/dist/controllers/index.d.ts +12 -0
- package/dist/controllers/index.d.ts.map +1 -1
- package/dist/controllers/index.js +6 -0
- package/dist/controllers/index.js.map +1 -1
- package/dist/db-fallback.d.ts.map +1 -1
- package/dist/db-fallback.js +14 -11
- package/dist/db-fallback.js.map +1 -1
- package/dist/examples/quic-sync-example.d.ts +9 -0
- package/dist/examples/quic-sync-example.d.ts.map +1 -0
- package/dist/examples/quic-sync-example.js +169 -0
- package/dist/examples/quic-sync-example.js.map +1 -0
- package/dist/types/quic.d.ts +518 -0
- package/dist/types/quic.d.ts.map +1 -0
- package/dist/types/quic.js +272 -0
- package/dist/types/quic.js.map +1 -0
- package/package.json +9 -3
- package/src/browser-entry.js +41 -6
- package/src/cli/agentdb-cli.ts +1114 -33
- package/src/controllers/ContextSynthesizer.ts +285 -0
- package/src/controllers/MMRDiversityRanker.ts +187 -0
- package/src/controllers/MetadataFilter.ts +280 -0
- package/src/controllers/QUICClient.ts +413 -0
- package/src/controllers/QUICServer.ts +498 -0
- package/src/controllers/SyncCoordinator.ts +597 -0
- package/src/controllers/WASMVectorSearch.ts +11 -2
- package/src/controllers/index.ts +12 -0
- package/src/db-fallback.ts +13 -10
- package/src/examples/quic-sync-example.ts +198 -0
- package/src/types/quic.ts +772 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MMR (Maximal Marginal Relevance) Diversity Ranking
|
|
3
|
+
*
|
|
4
|
+
* Implements MMR algorithm to select diverse results that balance
|
|
5
|
+
* relevance to query with diversity from already-selected results.
|
|
6
|
+
*
|
|
7
|
+
* Formula: MMR = argmax [λ × Sim(Di, Q) - (1-λ) × max Sim(Di, Dj)]
|
|
8
|
+
* Di∈R\S Dj∈S
|
|
9
|
+
*
|
|
10
|
+
* Where:
|
|
11
|
+
* - Di = candidate document
|
|
12
|
+
* - Q = query
|
|
13
|
+
* - S = already selected documents
|
|
14
|
+
* - λ = balance parameter (0 = max diversity, 1 = max relevance)
|
|
15
|
+
*/
|
|
16
|
+
export class MMRDiversityRanker {
|
|
17
|
+
/**
|
|
18
|
+
* Select diverse results using MMR algorithm
|
|
19
|
+
*
|
|
20
|
+
* @param candidates - All candidate results with embeddings
|
|
21
|
+
* @param queryEmbedding - Query vector
|
|
22
|
+
* @param options - MMR configuration
|
|
23
|
+
* @returns Diverse subset of candidates
|
|
24
|
+
*/
|
|
25
|
+
static selectDiverse(candidates, queryEmbedding, options = {}) {
|
|
26
|
+
const lambda = options.lambda ?? 0.5;
|
|
27
|
+
const k = options.k ?? 10;
|
|
28
|
+
const metric = options.metric ?? 'cosine';
|
|
29
|
+
if (candidates.length === 0) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
if (candidates.length <= k) {
|
|
33
|
+
return candidates;
|
|
34
|
+
}
|
|
35
|
+
// Calculate initial similarities to query
|
|
36
|
+
const candidatesWithSim = candidates.map(c => ({
|
|
37
|
+
...c,
|
|
38
|
+
similarity: c.similarity ?? this.calculateSimilarity(queryEmbedding, c.embedding, metric),
|
|
39
|
+
}));
|
|
40
|
+
const selected = [];
|
|
41
|
+
const remaining = [...candidatesWithSim];
|
|
42
|
+
// Select first item (highest relevance)
|
|
43
|
+
remaining.sort((a, b) => b.similarity - a.similarity);
|
|
44
|
+
selected.push(remaining.shift());
|
|
45
|
+
// Iteratively select items with highest MMR score
|
|
46
|
+
while (selected.length < k && remaining.length > 0) {
|
|
47
|
+
let maxMMR = -Infinity;
|
|
48
|
+
let maxIdx = 0;
|
|
49
|
+
for (let i = 0; i < remaining.length; i++) {
|
|
50
|
+
const candidate = remaining[i];
|
|
51
|
+
// Calculate max similarity to already-selected items
|
|
52
|
+
let maxSimToSelected = -Infinity;
|
|
53
|
+
for (const selectedItem of selected) {
|
|
54
|
+
const sim = this.calculateSimilarity(candidate.embedding, selectedItem.embedding, metric);
|
|
55
|
+
maxSimToSelected = Math.max(maxSimToSelected, sim);
|
|
56
|
+
}
|
|
57
|
+
// Calculate MMR score
|
|
58
|
+
const mmrScore = lambda * candidate.similarity - (1 - lambda) * maxSimToSelected;
|
|
59
|
+
if (mmrScore > maxMMR) {
|
|
60
|
+
maxMMR = mmrScore;
|
|
61
|
+
maxIdx = i;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Add item with highest MMR score
|
|
65
|
+
selected.push(remaining.splice(maxIdx, 1)[0]);
|
|
66
|
+
}
|
|
67
|
+
return selected;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Calculate similarity between two vectors
|
|
71
|
+
*/
|
|
72
|
+
static calculateSimilarity(vec1, vec2, metric) {
|
|
73
|
+
if (vec1.length !== vec2.length) {
|
|
74
|
+
throw new Error(`Vector dimension mismatch: ${vec1.length} vs ${vec2.length}`);
|
|
75
|
+
}
|
|
76
|
+
switch (metric) {
|
|
77
|
+
case 'cosine': {
|
|
78
|
+
let dot = 0, mag1 = 0, mag2 = 0;
|
|
79
|
+
for (let i = 0; i < vec1.length; i++) {
|
|
80
|
+
dot += vec1[i] * vec2[i];
|
|
81
|
+
mag1 += vec1[i] * vec1[i];
|
|
82
|
+
mag2 += vec2[i] * vec2[i];
|
|
83
|
+
}
|
|
84
|
+
return dot / (Math.sqrt(mag1) * Math.sqrt(mag2));
|
|
85
|
+
}
|
|
86
|
+
case 'euclidean': {
|
|
87
|
+
let sum = 0;
|
|
88
|
+
for (let i = 0; i < vec1.length; i++) {
|
|
89
|
+
const diff = vec1[i] - vec2[i];
|
|
90
|
+
sum += diff * diff;
|
|
91
|
+
}
|
|
92
|
+
return 1 / (1 + Math.sqrt(sum)); // Normalized to 0-1
|
|
93
|
+
}
|
|
94
|
+
case 'dot': {
|
|
95
|
+
let dot = 0;
|
|
96
|
+
for (let i = 0; i < vec1.length; i++) {
|
|
97
|
+
dot += vec1[i] * vec2[i];
|
|
98
|
+
}
|
|
99
|
+
return dot;
|
|
100
|
+
}
|
|
101
|
+
default:
|
|
102
|
+
throw new Error(`Unknown metric: ${metric}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Calculate diversity score for a set of results
|
|
107
|
+
*
|
|
108
|
+
* @param results - Results to analyze
|
|
109
|
+
* @param metric - Similarity metric
|
|
110
|
+
* @returns Average pairwise distance (higher = more diverse)
|
|
111
|
+
*/
|
|
112
|
+
static calculateDiversityScore(results, metric = 'cosine') {
|
|
113
|
+
if (results.length < 2) {
|
|
114
|
+
return 1.0; // Single result is maximally diverse
|
|
115
|
+
}
|
|
116
|
+
let totalDistance = 0;
|
|
117
|
+
let comparisons = 0;
|
|
118
|
+
for (let i = 0; i < results.length; i++) {
|
|
119
|
+
for (let j = i + 1; j < results.length; j++) {
|
|
120
|
+
const similarity = this.calculateSimilarity(results[i].embedding, results[j].embedding, metric);
|
|
121
|
+
// Convert similarity to distance
|
|
122
|
+
const distance = metric === 'cosine' ? 1 - similarity : similarity;
|
|
123
|
+
totalDistance += distance;
|
|
124
|
+
comparisons++;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return comparisons > 0 ? totalDistance / comparisons : 0;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=MMRDiversityRanker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MMRDiversityRanker.js","sourceRoot":"","sources":["../../src/controllers/MMRDiversityRanker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Metadata Filtering
|
|
3
|
+
*
|
|
4
|
+
* Implements MongoDB-style query operators for filtering
|
|
5
|
+
* episodes and patterns based on metadata fields.
|
|
6
|
+
*
|
|
7
|
+
* Supported operators:
|
|
8
|
+
* - $eq: Equal to
|
|
9
|
+
* - $ne: Not equal to
|
|
10
|
+
* - $gt: Greater than
|
|
11
|
+
* - $gte: Greater than or equal to
|
|
12
|
+
* - $lt: Less than
|
|
13
|
+
* - $lte: Less than or equal to
|
|
14
|
+
* - $in: Value is in array
|
|
15
|
+
* - $nin: Value is not in array
|
|
16
|
+
* - $contains: String/array contains value
|
|
17
|
+
* - $exists: Field exists
|
|
18
|
+
*/
|
|
19
|
+
export type FilterOperator = '$eq' | '$ne' | '$gt' | '$gte' | '$lt' | '$lte' | '$in' | '$nin' | '$contains' | '$exists';
|
|
20
|
+
export type FilterValue = string | number | boolean | string[] | number[] | {
|
|
21
|
+
[op in FilterOperator]?: any;
|
|
22
|
+
};
|
|
23
|
+
export interface MetadataFilters {
|
|
24
|
+
[field: string]: FilterValue;
|
|
25
|
+
}
|
|
26
|
+
export interface FilterableItem {
|
|
27
|
+
metadata?: any;
|
|
28
|
+
[key: string]: any;
|
|
29
|
+
}
|
|
30
|
+
export declare class MetadataFilter {
|
|
31
|
+
/**
|
|
32
|
+
* Apply filters to a collection of items
|
|
33
|
+
*
|
|
34
|
+
* @param items - Items to filter
|
|
35
|
+
* @param filters - MongoDB-style filter object
|
|
36
|
+
* @returns Filtered items
|
|
37
|
+
*/
|
|
38
|
+
static apply<T extends FilterableItem>(items: T[], filters: MetadataFilters): T[];
|
|
39
|
+
/**
|
|
40
|
+
* Check if an item matches all filters
|
|
41
|
+
*/
|
|
42
|
+
private static matchesFilters;
|
|
43
|
+
/**
|
|
44
|
+
* Check if an item matches a single filter
|
|
45
|
+
*/
|
|
46
|
+
private static matchesFilter;
|
|
47
|
+
/**
|
|
48
|
+
* Get field value from item (supports nested paths)
|
|
49
|
+
*/
|
|
50
|
+
private static getFieldValue;
|
|
51
|
+
/**
|
|
52
|
+
* Build SQL WHERE clause from filters (for database queries)
|
|
53
|
+
*
|
|
54
|
+
* @param filters - Metadata filters
|
|
55
|
+
* @param tableName - Table name for column references
|
|
56
|
+
* @returns SQL WHERE clause and parameters
|
|
57
|
+
*/
|
|
58
|
+
static toSQL(filters: MetadataFilters, tableName?: string): {
|
|
59
|
+
where: string;
|
|
60
|
+
params: any[];
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Validate filter object
|
|
64
|
+
*/
|
|
65
|
+
static validate(filters: MetadataFilters): {
|
|
66
|
+
valid: boolean;
|
|
67
|
+
errors: string[];
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=MetadataFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetadataFilter.d.ts","sourceRoot":"","sources":["../../src/controllers/MetadataFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;AAExH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG;KAAG,EAAE,IAAI,cAAc,CAAC,CAAC,EAAE,GAAG;CAAE,CAAC;AAE7G,MAAM,WAAW,eAAe;IAC9B,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;CAC9B;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,CAAC,SAAS,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,eAAe,GAAG,CAAC,EAAE;IAQjF;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,cAAc;IAS7B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAsE5B;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAwB5B;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,EAAE,SAAS,GAAE,MAAW,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,GAAG,EAAE,CAAA;KAAE;IAyFhG;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE;CAoBhF"}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced Metadata Filtering
|
|
3
|
+
*
|
|
4
|
+
* Implements MongoDB-style query operators for filtering
|
|
5
|
+
* episodes and patterns based on metadata fields.
|
|
6
|
+
*
|
|
7
|
+
* Supported operators:
|
|
8
|
+
* - $eq: Equal to
|
|
9
|
+
* - $ne: Not equal to
|
|
10
|
+
* - $gt: Greater than
|
|
11
|
+
* - $gte: Greater than or equal to
|
|
12
|
+
* - $lt: Less than
|
|
13
|
+
* - $lte: Less than or equal to
|
|
14
|
+
* - $in: Value is in array
|
|
15
|
+
* - $nin: Value is not in array
|
|
16
|
+
* - $contains: String/array contains value
|
|
17
|
+
* - $exists: Field exists
|
|
18
|
+
*/
|
|
19
|
+
export class MetadataFilter {
|
|
20
|
+
/**
|
|
21
|
+
* Apply filters to a collection of items
|
|
22
|
+
*
|
|
23
|
+
* @param items - Items to filter
|
|
24
|
+
* @param filters - MongoDB-style filter object
|
|
25
|
+
* @returns Filtered items
|
|
26
|
+
*/
|
|
27
|
+
static apply(items, filters) {
|
|
28
|
+
if (!filters || Object.keys(filters).length === 0) {
|
|
29
|
+
return items;
|
|
30
|
+
}
|
|
31
|
+
return items.filter(item => this.matchesFilters(item, filters));
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if an item matches all filters
|
|
35
|
+
*/
|
|
36
|
+
static matchesFilters(item, filters) {
|
|
37
|
+
for (const [field, filter] of Object.entries(filters)) {
|
|
38
|
+
if (!this.matchesFilter(item, field, filter)) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if an item matches a single filter
|
|
46
|
+
*/
|
|
47
|
+
static matchesFilter(item, field, filter) {
|
|
48
|
+
// Get field value (supports nested paths like "metadata.year")
|
|
49
|
+
const value = this.getFieldValue(item, field);
|
|
50
|
+
// Handle simple equality
|
|
51
|
+
if (typeof filter !== 'object' || Array.isArray(filter)) {
|
|
52
|
+
return value === filter;
|
|
53
|
+
}
|
|
54
|
+
// Handle operator-based filters
|
|
55
|
+
const operators = filter;
|
|
56
|
+
for (const [operator, operand] of Object.entries(operators)) {
|
|
57
|
+
switch (operator) {
|
|
58
|
+
case '$eq':
|
|
59
|
+
if (value !== operand)
|
|
60
|
+
return false;
|
|
61
|
+
break;
|
|
62
|
+
case '$ne':
|
|
63
|
+
if (value === operand)
|
|
64
|
+
return false;
|
|
65
|
+
break;
|
|
66
|
+
case '$gt':
|
|
67
|
+
if (!(value > operand))
|
|
68
|
+
return false;
|
|
69
|
+
break;
|
|
70
|
+
case '$gte':
|
|
71
|
+
if (!(value >= operand))
|
|
72
|
+
return false;
|
|
73
|
+
break;
|
|
74
|
+
case '$lt':
|
|
75
|
+
if (!(value < operand))
|
|
76
|
+
return false;
|
|
77
|
+
break;
|
|
78
|
+
case '$lte':
|
|
79
|
+
if (!(value <= operand))
|
|
80
|
+
return false;
|
|
81
|
+
break;
|
|
82
|
+
case '$in':
|
|
83
|
+
if (!Array.isArray(operand) || !operand.includes(value))
|
|
84
|
+
return false;
|
|
85
|
+
break;
|
|
86
|
+
case '$nin':
|
|
87
|
+
if (!Array.isArray(operand) || operand.includes(value))
|
|
88
|
+
return false;
|
|
89
|
+
break;
|
|
90
|
+
case '$contains':
|
|
91
|
+
if (typeof value === 'string') {
|
|
92
|
+
if (!value.includes(operand))
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
else if (Array.isArray(value)) {
|
|
96
|
+
if (!value.includes(operand))
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
103
|
+
case '$exists':
|
|
104
|
+
const exists = value !== undefined && value !== null;
|
|
105
|
+
if (exists !== operand)
|
|
106
|
+
return false;
|
|
107
|
+
break;
|
|
108
|
+
default:
|
|
109
|
+
console.warn(`Unknown operator: ${operator}`);
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get field value from item (supports nested paths)
|
|
117
|
+
*/
|
|
118
|
+
static getFieldValue(item, field) {
|
|
119
|
+
const parts = field.split('.');
|
|
120
|
+
let value = item;
|
|
121
|
+
for (const part of parts) {
|
|
122
|
+
if (value === null || value === undefined) {
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
// Parse metadata JSON if needed
|
|
126
|
+
if (part === 'metadata' && typeof value.metadata === 'string') {
|
|
127
|
+
try {
|
|
128
|
+
value.metadata = JSON.parse(value.metadata);
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
value = value[part];
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Build SQL WHERE clause from filters (for database queries)
|
|
140
|
+
*
|
|
141
|
+
* @param filters - Metadata filters
|
|
142
|
+
* @param tableName - Table name for column references
|
|
143
|
+
* @returns SQL WHERE clause and parameters
|
|
144
|
+
*/
|
|
145
|
+
static toSQL(filters, tableName = '') {
|
|
146
|
+
const conditions = [];
|
|
147
|
+
const params = [];
|
|
148
|
+
const prefix = tableName ? `${tableName}.` : '';
|
|
149
|
+
for (const [field, filter] of Object.entries(filters)) {
|
|
150
|
+
// For metadata fields, use JSON extraction
|
|
151
|
+
const isMetadata = field.startsWith('metadata.');
|
|
152
|
+
const columnRef = isMetadata
|
|
153
|
+
? `json_extract(${prefix}metadata, '$.${field.slice(9)}')`
|
|
154
|
+
: `${prefix}${field}`;
|
|
155
|
+
if (typeof filter !== 'object' || Array.isArray(filter)) {
|
|
156
|
+
// Simple equality
|
|
157
|
+
conditions.push(`${columnRef} = ?`);
|
|
158
|
+
params.push(filter);
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
// Operator-based filters
|
|
162
|
+
const operators = filter;
|
|
163
|
+
for (const [operator, operand] of Object.entries(operators)) {
|
|
164
|
+
switch (operator) {
|
|
165
|
+
case '$eq':
|
|
166
|
+
conditions.push(`${columnRef} = ?`);
|
|
167
|
+
params.push(operand);
|
|
168
|
+
break;
|
|
169
|
+
case '$ne':
|
|
170
|
+
conditions.push(`${columnRef} != ?`);
|
|
171
|
+
params.push(operand);
|
|
172
|
+
break;
|
|
173
|
+
case '$gt':
|
|
174
|
+
conditions.push(`${columnRef} > ?`);
|
|
175
|
+
params.push(operand);
|
|
176
|
+
break;
|
|
177
|
+
case '$gte':
|
|
178
|
+
conditions.push(`${columnRef} >= ?`);
|
|
179
|
+
params.push(operand);
|
|
180
|
+
break;
|
|
181
|
+
case '$lt':
|
|
182
|
+
conditions.push(`${columnRef} < ?`);
|
|
183
|
+
params.push(operand);
|
|
184
|
+
break;
|
|
185
|
+
case '$lte':
|
|
186
|
+
conditions.push(`${columnRef} <= ?`);
|
|
187
|
+
params.push(operand);
|
|
188
|
+
break;
|
|
189
|
+
case '$in':
|
|
190
|
+
if (Array.isArray(operand)) {
|
|
191
|
+
const placeholders = operand.map(() => '?').join(', ');
|
|
192
|
+
conditions.push(`${columnRef} IN (${placeholders})`);
|
|
193
|
+
params.push(...operand);
|
|
194
|
+
}
|
|
195
|
+
break;
|
|
196
|
+
case '$nin':
|
|
197
|
+
if (Array.isArray(operand)) {
|
|
198
|
+
const placeholders = operand.map(() => '?').join(', ');
|
|
199
|
+
conditions.push(`${columnRef} NOT IN (${placeholders})`);
|
|
200
|
+
params.push(...operand);
|
|
201
|
+
}
|
|
202
|
+
break;
|
|
203
|
+
case '$contains':
|
|
204
|
+
conditions.push(`${columnRef} LIKE ?`);
|
|
205
|
+
params.push(`%${operand}%`);
|
|
206
|
+
break;
|
|
207
|
+
case '$exists':
|
|
208
|
+
if (operand) {
|
|
209
|
+
conditions.push(`${columnRef} IS NOT NULL`);
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
conditions.push(`${columnRef} IS NULL`);
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
const where = conditions.length > 0 ? conditions.join(' AND ') : '1=1';
|
|
220
|
+
return { where, params };
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Validate filter object
|
|
224
|
+
*/
|
|
225
|
+
static validate(filters) {
|
|
226
|
+
const errors = [];
|
|
227
|
+
for (const [field, filter] of Object.entries(filters)) {
|
|
228
|
+
if (!field || field.trim() === '') {
|
|
229
|
+
errors.push('Filter field name cannot be empty');
|
|
230
|
+
}
|
|
231
|
+
if (typeof filter === 'object' && !Array.isArray(filter)) {
|
|
232
|
+
const operators = Object.keys(filter);
|
|
233
|
+
for (const op of operators) {
|
|
234
|
+
if (!op.startsWith('$')) {
|
|
235
|
+
errors.push(`Invalid operator: ${op} (must start with $)`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return { valid: errors.length === 0, errors };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
//# sourceMappingURL=MetadataFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MetadataFilter.js","sourceRoot":"","sources":["../../src/controllers/MetadataFilter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAeH,MAAM,OAAO,cAAc;IACzB;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAA2B,KAAU,EAAE,OAAwB;QACzE,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClD,OAAO,KAAK,CAAC;QACf,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAClE,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,cAAc,CAAC,IAAoB,EAAE,OAAwB;QAC1E,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC7C,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,aAAa,CAAC,IAAoB,EAAE,KAAa,EAAE,MAAmB;QACnF,+DAA+D;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAE9C,yBAAyB;QACzB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACxD,OAAO,KAAK,KAAK,MAAM,CAAC;QAC1B,CAAC;QAED,gCAAgC;QAChC,MAAM,SAAS,GAAG,MAA0C,CAAC;QAE7D,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC5D,QAAQ,QAA0B,EAAE,CAAC;gBACnC,KAAK,KAAK;oBACR,IAAI,KAAK,KAAK,OAAO;wBAAE,OAAO,KAAK,CAAC;oBACpC,MAAM;gBAER,KAAK,KAAK;oBACR,IAAI,KAAK,KAAK,OAAO;wBAAE,OAAO,KAAK,CAAC;oBACpC,MAAM;gBAER,KAAK,KAAK;oBACR,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC;wBAAE,OAAO,KAAK,CAAC;oBACrC,MAAM;gBAER,KAAK,MAAM;oBACT,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;wBAAE,OAAO,KAAK,CAAC;oBACtC,MAAM;gBAER,KAAK,KAAK;oBACR,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC;wBAAE,OAAO,KAAK,CAAC;oBACrC,MAAM;gBAER,KAAK,MAAM;oBACT,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,CAAC;wBAAE,OAAO,KAAK,CAAC;oBACtC,MAAM;gBAER,KAAK,KAAK;oBACR,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;wBAAE,OAAO,KAAK,CAAC;oBACtE,MAAM;gBAER,KAAK,MAAM;oBACT,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;wBAAE,OAAO,KAAK,CAAC;oBACrE,MAAM;gBAER,KAAK,WAAW;oBACd,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;wBAC9B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;4BAAE,OAAO,KAAK,CAAC;oBAC7C,CAAC;yBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;wBAChC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC;4BAAE,OAAO,KAAK,CAAC;oBAC7C,CAAC;yBAAM,CAAC;wBACN,OAAO,KAAK,CAAC;oBACf,CAAC;oBACD,MAAM;gBAER,KAAK,SAAS;oBACZ,MAAM,MAAM,GAAG,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;oBACrD,IAAI,MAAM,KAAK,OAAO;wBAAE,OAAO,KAAK,CAAC;oBACrC,MAAM;gBAER;oBACE,OAAO,CAAC,IAAI,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;oBAC9C,OAAO,KAAK,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,aAAa,CAAC,IAAoB,EAAE,KAAa;QAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAQ,IAAI,CAAC;QAEtB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC1C,OAAO,SAAS,CAAC;YACnB,CAAC;YAED,gCAAgC;YAChC,IAAI,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC9D,IAAI,CAAC;oBACH,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC9C,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC;YAED,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,OAAwB,EAAE,YAAoB,EAAE;QAC3D,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,MAAM,MAAM,GAAU,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAEhD,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,2CAA2C;YAC3C,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;YACjD,MAAM,SAAS,GAAG,UAAU;gBAC1B,CAAC,CAAC,gBAAgB,MAAM,gBAAgB,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;gBAC1D,CAAC,CAAC,GAAG,MAAM,GAAG,KAAK,EAAE,CAAC;YAExB,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxD,kBAAkB;gBAClB,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,yBAAyB;gBACzB,MAAM,SAAS,GAAG,MAA0C,CAAC;gBAE7D,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC5D,QAAQ,QAA0B,EAAE,CAAC;wBACnC,KAAK,KAAK;4BACR,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC;4BACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrB,MAAM;wBAER,KAAK,KAAK;4BACR,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC;4BACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrB,MAAM;wBAER,KAAK,KAAK;4BACR,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC;4BACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrB,MAAM;wBAER,KAAK,MAAM;4BACT,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC;4BACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrB,MAAM;wBAER,KAAK,KAAK;4BACR,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC;4BACpC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrB,MAAM;wBAER,KAAK,MAAM;4BACT,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC;4BACrC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BACrB,MAAM;wBAER,KAAK,KAAK;4BACR,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gCAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gCACvD,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,QAAQ,YAAY,GAAG,CAAC,CAAC;gCACrD,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;4BAC1B,CAAC;4BACD,MAAM;wBAER,KAAK,MAAM;4BACT,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gCAC3B,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gCACvD,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,YAAY,YAAY,GAAG,CAAC,CAAC;gCACzD,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC;4BAC1B,CAAC;4BACD,MAAM;wBAER,KAAK,WAAW;4BACd,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC;4BACvC,MAAM,CAAC,IAAI,CAAC,IAAI,OAAO,GAAG,CAAC,CAAC;4BAC5B,MAAM;wBAER,KAAK,SAAS;4BACZ,IAAI,OAAO,EAAE,CAAC;gCACZ,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,cAAc,CAAC,CAAC;4BAC9C,CAAC;iCAAM,CAAC;gCACN,UAAU,CAAC,IAAI,CAAC,GAAG,SAAS,UAAU,CAAC,CAAC;4BAC1C,CAAC;4BACD,MAAM;oBACV,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACvE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,OAAwB;QACtC,MAAM,MAAM,GAAa,EAAE,CAAC;QAE5B,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtD,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAClC,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YACnD,CAAC;YAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtC,KAAK,MAAM,EAAE,IAAI,SAAS,EAAE,CAAC;oBAC3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACxB,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,sBAAsB,CAAC,CAAC;oBAC7D,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QUICClient - QUIC Protocol Client for AgentDB Synchronization
|
|
3
|
+
*
|
|
4
|
+
* Implements a QUIC client for initiating synchronization requests to remote
|
|
5
|
+
* AgentDB instances. Supports connection pooling, retry logic, and reliable sync.
|
|
6
|
+
*
|
|
7
|
+
* Features:
|
|
8
|
+
* - Connect to remote QUIC servers
|
|
9
|
+
* - Send sync requests (episodes, skills, edges)
|
|
10
|
+
* - Handle responses and errors
|
|
11
|
+
* - Automatic retry with exponential backoff
|
|
12
|
+
* - Connection pooling for efficiency
|
|
13
|
+
* - Comprehensive error handling
|
|
14
|
+
*/
|
|
15
|
+
export interface QUICClientConfig {
|
|
16
|
+
serverHost: string;
|
|
17
|
+
serverPort: number;
|
|
18
|
+
authToken?: string;
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
retryDelayMs?: number;
|
|
21
|
+
timeoutMs?: number;
|
|
22
|
+
poolSize?: number;
|
|
23
|
+
tlsConfig?: {
|
|
24
|
+
cert?: string;
|
|
25
|
+
key?: string;
|
|
26
|
+
ca?: string;
|
|
27
|
+
rejectUnauthorized?: boolean;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface SyncOptions {
|
|
31
|
+
type: 'episodes' | 'skills' | 'edges' | 'full';
|
|
32
|
+
since?: number;
|
|
33
|
+
filters?: Record<string, any>;
|
|
34
|
+
batchSize?: number;
|
|
35
|
+
onProgress?: (progress: SyncProgress) => void;
|
|
36
|
+
}
|
|
37
|
+
export interface SyncProgress {
|
|
38
|
+
phase: 'connecting' | 'syncing' | 'processing' | 'completed' | 'error';
|
|
39
|
+
itemsSynced?: number;
|
|
40
|
+
totalItems?: number;
|
|
41
|
+
bytesTransferred?: number;
|
|
42
|
+
error?: string;
|
|
43
|
+
}
|
|
44
|
+
export interface SyncResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
data?: any;
|
|
47
|
+
itemsReceived: number;
|
|
48
|
+
bytesTransferred: number;
|
|
49
|
+
durationMs: number;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
52
|
+
export declare class QUICClient {
|
|
53
|
+
private config;
|
|
54
|
+
private connectionPool;
|
|
55
|
+
private isConnected;
|
|
56
|
+
private retryCount;
|
|
57
|
+
constructor(config: QUICClientConfig);
|
|
58
|
+
/**
|
|
59
|
+
* Connect to remote QUIC server
|
|
60
|
+
*/
|
|
61
|
+
connect(): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Disconnect from server
|
|
64
|
+
*/
|
|
65
|
+
disconnect(): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Send sync request to server
|
|
68
|
+
*/
|
|
69
|
+
sync(options: SyncOptions): Promise<SyncResult>;
|
|
70
|
+
/**
|
|
71
|
+
* Send request with automatic retry
|
|
72
|
+
*/
|
|
73
|
+
private sendWithRetry;
|
|
74
|
+
/**
|
|
75
|
+
* Send request to server
|
|
76
|
+
*/
|
|
77
|
+
private sendRequest;
|
|
78
|
+
/**
|
|
79
|
+
* Acquire connection from pool
|
|
80
|
+
*/
|
|
81
|
+
private acquireConnection;
|
|
82
|
+
/**
|
|
83
|
+
* Release connection back to pool
|
|
84
|
+
*/
|
|
85
|
+
private releaseConnection;
|
|
86
|
+
/**
|
|
87
|
+
* Get client status
|
|
88
|
+
*/
|
|
89
|
+
getStatus(): {
|
|
90
|
+
isConnected: boolean;
|
|
91
|
+
poolSize: number;
|
|
92
|
+
activeConnections: number;
|
|
93
|
+
totalRequests: number;
|
|
94
|
+
config: QUICClientConfig;
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Test connection to server
|
|
98
|
+
*/
|
|
99
|
+
ping(): Promise<{
|
|
100
|
+
success: boolean;
|
|
101
|
+
latencyMs: number;
|
|
102
|
+
error?: string;
|
|
103
|
+
}>;
|
|
104
|
+
/**
|
|
105
|
+
* Sleep helper
|
|
106
|
+
*/
|
|
107
|
+
private sleep;
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=QUICClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"QUICClient.d.ts","sourceRoot":"","sources":["../../src/controllers/QUICClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,kBAAkB,CAAC,EAAE,OAAO,CAAC;KAC9B,CAAC;CACH;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,YAAY,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,GAAG,OAAO,CAAC;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,UAAU,CAAa;gBAEnB,MAAM,EAAE,gBAAgB;IAapC;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAsC9B;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBjC;;OAEG;IACG,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;IAiGrD;;OAEG;YACW,aAAa;IA8B3B;;OAEG;YACW,WAAW;IAkBzB;;OAEG;YACW,iBAAiB;IAkB/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAKzB;;OAEG;IACH,SAAS,IAAI;QACX,WAAW,EAAE,OAAO,CAAC;QACrB,QAAQ,EAAE,MAAM,CAAC;QACjB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,MAAM,EAAE,gBAAgB,CAAC;KAC1B;IAoBD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAqC9E;;OAEG;IACH,OAAO,CAAC,KAAK;CAGd"}
|