@feltdb/core 0.2.0 → 0.4.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/LICENSE +19 -0
- package/dist/analytics-backend.d.ts +39 -0
- package/dist/analytics-backend.d.ts.map +1 -0
- package/dist/analytics-backend.js +152 -0
- package/dist/application-contract.d.ts +49 -0
- package/dist/application-contract.d.ts.map +1 -0
- package/dist/application-contract.js +13 -0
- package/dist/application-manifest.d.ts +305 -0
- package/dist/application-manifest.d.ts.map +1 -0
- package/dist/application-manifest.js +26 -0
- package/dist/artifact.d.ts +73 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +21 -0
- package/dist/authorization.d.ts +99 -0
- package/dist/authorization.d.ts.map +1 -0
- package/dist/authorization.js +15 -0
- package/dist/bundle.d.ts +55 -0
- package/dist/bundle.d.ts.map +1 -0
- package/dist/bundle.js +13 -0
- package/dist/collection.d.ts +28 -0
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +83 -0
- package/dist/db.d.ts +18 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +20 -8
- package/dist/distributed-indexing.d.ts +170 -0
- package/dist/distributed-indexing.d.ts.map +1 -0
- package/dist/distributed-indexing.js +260 -0
- package/dist/flowspec.d.ts +4 -0
- package/dist/flowspec.d.ts.map +1 -1
- package/dist/flowspec.js +8 -0
- package/dist/http-client.d.ts +35 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +70 -0
- package/dist/identity.d.ts +40 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +10 -0
- package/dist/index-analytics.d.ts +121 -0
- package/dist/index-analytics.d.ts.map +1 -0
- package/dist/index-analytics.js +279 -0
- package/dist/index-backend.d.ts +26 -0
- package/dist/index-backend.d.ts.map +1 -0
- package/dist/index-backend.js +115 -0
- package/dist/index-dashboard.d.ts +114 -0
- package/dist/index-dashboard.d.ts.map +1 -0
- package/dist/index-dashboard.js +256 -0
- package/dist/index-manager.d.ts +18 -0
- package/dist/index-manager.d.ts.map +1 -0
- package/dist/index-manager.js +333 -0
- package/dist/index-monitoring.d.ts +133 -0
- package/dist/index-monitoring.d.ts.map +1 -0
- package/dist/index-monitoring.js +218 -0
- package/dist/index-recovery.d.ts +57 -0
- package/dist/index-recovery.d.ts.map +1 -0
- package/dist/index-recovery.js +117 -0
- package/dist/index-store.d.ts +62 -0
- package/dist/index-store.d.ts.map +1 -0
- package/dist/index-store.js +141 -0
- package/dist/index-types.d.ts +70 -0
- package/dist/index-types.d.ts.map +1 -0
- package/dist/index-types.js +6 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -0
- package/dist/observe.d.ts +51 -0
- package/dist/observe.d.ts.map +1 -0
- package/dist/observe.js +14 -0
- package/dist/protocol.d.ts +25 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +18 -0
- package/dist/provider.d.ts +61 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +17 -0
- package/dist/query-planner.d.ts +69 -0
- package/dist/query-planner.d.ts.map +1 -0
- package/dist/query-planner.js +184 -0
- package/dist/release.d.ts +60 -0
- package/dist/release.d.ts.map +1 -0
- package/dist/release.js +18 -0
- package/dist/sharding.d.ts +159 -0
- package/dist/sharding.d.ts.map +1 -0
- package/dist/sharding.js +317 -0
- package/dist/state-contract.d.ts +173 -0
- package/dist/state-contract.d.ts.map +1 -0
- package/dist/state-contract.js +24 -0
- package/dist/sync-contract.d.ts +101 -0
- package/dist/sync-contract.d.ts.map +1 -0
- package/dist/sync-contract.js +90 -0
- package/dist/worker.d.ts +90 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +26 -0
- package/dist/workload.d.ts +102 -0
- package/dist/workload.d.ts.map +1 -0
- package/dist/workload.js +23 -0
- package/package.json +17 -5
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Query Planner - Cost-Based Index Selection
|
|
3
|
+
*
|
|
4
|
+
* Analyzes queries and selects the optimal index to use.
|
|
5
|
+
* Uses cardinality estimation and index statistics to minimize query cost.
|
|
6
|
+
*/
|
|
7
|
+
export class QueryPlanner {
|
|
8
|
+
/**
|
|
9
|
+
* Analyze a predicate and select the best index.
|
|
10
|
+
*/
|
|
11
|
+
static planQuery(predicates, indexes) {
|
|
12
|
+
if (indexes.length === 0) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const scoreboard = indexes.map(index => this.scoreIndex(predicates, index));
|
|
16
|
+
// Return index with highest score (best coverage and lowest cost)
|
|
17
|
+
return scoreboard.reduce((best, current) => (current.score > best.score ? current : best));
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Score how well an index covers the given predicates.
|
|
21
|
+
*/
|
|
22
|
+
static scoreIndex(predicates, index) {
|
|
23
|
+
const indexFields = index.fields || (index.field ? [index.field] : []);
|
|
24
|
+
const textFields = index.textFields || [];
|
|
25
|
+
const allIndexFields = [...indexFields, ...textFields];
|
|
26
|
+
// Calculate coverage: how many predicates can this index handle
|
|
27
|
+
const coveredPredicates = predicates.filter(p => allIndexFields.includes(p.field));
|
|
28
|
+
const coverage = coveredPredicates.length / Math.max(predicates.length, 1);
|
|
29
|
+
// Calculate cost based on index type
|
|
30
|
+
let cost = 100; // Base cost
|
|
31
|
+
let estimatedRows = 1000; // Base estimate
|
|
32
|
+
if (index.type === 'hash') {
|
|
33
|
+
// Hash index: O(1) lookup
|
|
34
|
+
cost = coveredPredicates.length > 0 ? 5 : 100;
|
|
35
|
+
estimatedRows = coveredPredicates.length > 0 ? 10 : 1000;
|
|
36
|
+
}
|
|
37
|
+
else if (index.type === 'sorted') {
|
|
38
|
+
// Sorted index: O(log n) lookup
|
|
39
|
+
cost = coveredPredicates.length > 0 ? 10 : 100;
|
|
40
|
+
estimatedRows = coveredPredicates.length > 0 ? 50 : 1000;
|
|
41
|
+
}
|
|
42
|
+
else if (index.type === 'compound') {
|
|
43
|
+
// Compound index: benefits from multiple field coverage
|
|
44
|
+
const matchedFields = indexFields.filter(f => predicates.some(p => p.field === f));
|
|
45
|
+
const matchRatio = matchedFields.length / indexFields.length;
|
|
46
|
+
cost = matchRatio > 0.5 ? 8 : 50;
|
|
47
|
+
estimatedRows = matchRatio > 0.5 ? 20 : 500;
|
|
48
|
+
}
|
|
49
|
+
else if (index.type === 'text') {
|
|
50
|
+
// Text index: for full-text search
|
|
51
|
+
cost = coveredPredicates.some(p => p.operator === 'contains') ? 15 : 100;
|
|
52
|
+
estimatedRows = coveredPredicates.some(p => p.operator === 'contains') ? 100 : 1000;
|
|
53
|
+
}
|
|
54
|
+
// Bonus for exact matches and range queries
|
|
55
|
+
const exactMatches = coveredPredicates.filter(p => p.operator === 'eq' || p.operator === 'range').length;
|
|
56
|
+
cost -= exactMatches * 2;
|
|
57
|
+
// Score: higher coverage and lower cost is better
|
|
58
|
+
const score = coverage * 100 - cost;
|
|
59
|
+
return {
|
|
60
|
+
indexName: index.name,
|
|
61
|
+
indexType: index.type,
|
|
62
|
+
fields: allIndexFields,
|
|
63
|
+
score: Math.max(0, score),
|
|
64
|
+
coverage,
|
|
65
|
+
estimatedRows,
|
|
66
|
+
cost,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Explain the query plan (for debugging).
|
|
71
|
+
*/
|
|
72
|
+
static explainPlan(predicates, indexes, selectedIndex) {
|
|
73
|
+
if (indexes.length === 0) {
|
|
74
|
+
return 'FULL_SCAN: No indexes available';
|
|
75
|
+
}
|
|
76
|
+
if (!selectedIndex) {
|
|
77
|
+
return 'FULL_SCAN: No suitable index found';
|
|
78
|
+
}
|
|
79
|
+
return (`INDEX_SCAN: ${selectedIndex.indexName} (${selectedIndex.indexType}) ` +
|
|
80
|
+
`coverage=${(selectedIndex.coverage * 100).toFixed(0)}% ` +
|
|
81
|
+
`cost=${selectedIndex.cost} ` +
|
|
82
|
+
`estimatedRows=${selectedIndex.estimatedRows}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Compound query builder for multi-field searches.
|
|
87
|
+
*/
|
|
88
|
+
export class CompoundQuery {
|
|
89
|
+
constructor() {
|
|
90
|
+
this.predicates = new Map();
|
|
91
|
+
this.fields = [];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Add a predicate for a field.
|
|
95
|
+
*/
|
|
96
|
+
addPredicate(field, operator, value) {
|
|
97
|
+
this.predicates.set(field, { field, operator, value });
|
|
98
|
+
if (!this.fields.includes(field)) {
|
|
99
|
+
this.fields.push(field);
|
|
100
|
+
}
|
|
101
|
+
return this;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Get all predicates.
|
|
105
|
+
*/
|
|
106
|
+
getPredicates() {
|
|
107
|
+
return Array.from(this.predicates.values());
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get fields involved in this query.
|
|
111
|
+
*/
|
|
112
|
+
getFields() {
|
|
113
|
+
return [...this.fields];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Find best index for this compound query.
|
|
117
|
+
*/
|
|
118
|
+
planWith(indexes) {
|
|
119
|
+
return QueryPlanner.planQuery(this.getPredicates(), indexes);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Index recommendation engine - suggests indexes to create.
|
|
124
|
+
*/
|
|
125
|
+
export class IndexRecommender {
|
|
126
|
+
/**
|
|
127
|
+
* Analyze query patterns and recommend indexes.
|
|
128
|
+
*/
|
|
129
|
+
static recommendIndexes(queries) {
|
|
130
|
+
const fieldFrequency = new Map();
|
|
131
|
+
const fieldOperators = new Map();
|
|
132
|
+
// Analyze query patterns
|
|
133
|
+
for (const query of queries) {
|
|
134
|
+
for (const predicate of query) {
|
|
135
|
+
fieldFrequency.set(predicate.field, (fieldFrequency.get(predicate.field) || 0) + 1);
|
|
136
|
+
if (!fieldOperators.has(predicate.field)) {
|
|
137
|
+
fieldOperators.set(predicate.field, new Set());
|
|
138
|
+
}
|
|
139
|
+
fieldOperators.get(predicate.field).add(predicate.operator);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const recommendations = [];
|
|
143
|
+
const totalQueries = queries.length;
|
|
144
|
+
// Recommend indexes for frequently queried fields
|
|
145
|
+
for (const [field, frequency] of fieldFrequency) {
|
|
146
|
+
const queryRatio = frequency / totalQueries;
|
|
147
|
+
// Only recommend indexes for fields queried in > 10% of queries
|
|
148
|
+
if (queryRatio < 0.1)
|
|
149
|
+
continue;
|
|
150
|
+
const operators = fieldOperators.get(field);
|
|
151
|
+
// Recommend hash index for equality queries
|
|
152
|
+
if (operators.has('eq') && queryRatio > 0.15) {
|
|
153
|
+
recommendations.push({
|
|
154
|
+
name: `idx_${field}_hash`,
|
|
155
|
+
type: 'hash',
|
|
156
|
+
field,
|
|
157
|
+
inmemory: true,
|
|
158
|
+
persistent: true,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// Recommend sorted index for range queries
|
|
162
|
+
if ((operators.has('gt') || operators.has('lt') || operators.has('range')) && queryRatio > 0.1) {
|
|
163
|
+
recommendations.push({
|
|
164
|
+
name: `idx_${field}_sorted`,
|
|
165
|
+
type: 'sorted',
|
|
166
|
+
field,
|
|
167
|
+
inmemory: true,
|
|
168
|
+
persistent: true,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
// Recommend text index for text search
|
|
172
|
+
if (operators.has('contains') && queryRatio > 0.1) {
|
|
173
|
+
recommendations.push({
|
|
174
|
+
name: `idx_${field}_text`,
|
|
175
|
+
type: 'text',
|
|
176
|
+
textFields: [field],
|
|
177
|
+
inmemory: true,
|
|
178
|
+
persistent: true,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return recommendations;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface CiAttestation {
|
|
2
|
+
provider: string;
|
|
3
|
+
run_id: string;
|
|
4
|
+
commit: string;
|
|
5
|
+
status: string;
|
|
6
|
+
checks: Record<string, boolean>;
|
|
7
|
+
artifacts: Record<string, string>;
|
|
8
|
+
generated_at: number | string;
|
|
9
|
+
}
|
|
10
|
+
export interface ReleaseManifest {
|
|
11
|
+
release_id: string;
|
|
12
|
+
version: string;
|
|
13
|
+
application_id: string;
|
|
14
|
+
revision_id: string;
|
|
15
|
+
bundle_id: string;
|
|
16
|
+
source_commit: string;
|
|
17
|
+
artifacts: {
|
|
18
|
+
name: string;
|
|
19
|
+
artifact_type: string;
|
|
20
|
+
digest: string;
|
|
21
|
+
size: number;
|
|
22
|
+
}[];
|
|
23
|
+
packages: {
|
|
24
|
+
name: string;
|
|
25
|
+
artifact_type: string;
|
|
26
|
+
digest: string;
|
|
27
|
+
size: number;
|
|
28
|
+
}[];
|
|
29
|
+
runtime: Record<string, string>;
|
|
30
|
+
environment: Record<string, string>;
|
|
31
|
+
parent_release?: string;
|
|
32
|
+
ci_attestation: CiAttestation;
|
|
33
|
+
release_attestation?: string;
|
|
34
|
+
digest: string;
|
|
35
|
+
created_at: number;
|
|
36
|
+
}
|
|
37
|
+
export interface Release {
|
|
38
|
+
manifest: ReleaseManifest;
|
|
39
|
+
status: 'CANDIDATE' | 'VERIFIED' | 'PROMOTED' | 'REVOKED';
|
|
40
|
+
created_by: string;
|
|
41
|
+
}
|
|
42
|
+
export declare class ReleaseClient {
|
|
43
|
+
private baseUrl;
|
|
44
|
+
private fetcher;
|
|
45
|
+
constructor(baseUrl?: string, fetcher?: typeof fetch);
|
|
46
|
+
private json;
|
|
47
|
+
create(manifest: ReleaseManifest): Promise<Release>;
|
|
48
|
+
list(applicationId: string): Promise<{
|
|
49
|
+
releases: Release[];
|
|
50
|
+
}>;
|
|
51
|
+
get(id: string): Promise<Release>;
|
|
52
|
+
verify(id: string): Promise<Release>;
|
|
53
|
+
promote(id: string, applicationId: string, environment: string): Promise<Release>;
|
|
54
|
+
plan(releaseId: string, environment: string, rollbackTarget?: string): Promise<unknown>;
|
|
55
|
+
deploy(plan: unknown): Promise<unknown>;
|
|
56
|
+
status(id: string): Promise<unknown>;
|
|
57
|
+
health(id: string): Promise<unknown>;
|
|
58
|
+
stop(id: string): Promise<unknown>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=release.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAAC,QAAQ,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC,MAAM,EAAC,OAAO,CAAC,CAAC;IAAA,SAAS,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;IAAA,YAAY,EAAC,MAAM,GAAC,MAAM,CAAA;CAAC;AAClL,MAAM,WAAW,eAAe;IAAC,UAAU,EAAC,MAAM,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,MAAM,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC,MAAM,CAAC;IAAA,aAAa,EAAC,MAAM,CAAC;IAAA,SAAS,EAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,MAAM,EAAC,MAAM,CAAC;QAAA,IAAI,EAAC,MAAM,CAAA;KAAC,EAAE,CAAC;IAAA,QAAQ,EAAC;QAAC,IAAI,EAAC,MAAM,CAAC;QAAA,aAAa,EAAC,MAAM,CAAC;QAAA,MAAM,EAAC,MAAM,CAAC;QAAA,IAAI,EAAC,MAAM,CAAA;KAAC,EAAE,CAAC;IAAA,OAAO,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;IAAA,WAAW,EAAC,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;IAAA,cAAc,CAAC,EAAC,MAAM,CAAC;IAAA,cAAc,EAAC,aAAa,CAAC;IAAA,mBAAmB,CAAC,EAAC,MAAM,CAAC;IAAA,MAAM,EAAC,MAAM,CAAC;IAAA,UAAU,EAAC,MAAM,CAAA;CAAC;AACld,MAAM,WAAW,OAAO;IAAC,QAAQ,EAAC,eAAe,CAAC;IAAA,MAAM,EAAC,WAAW,GAAC,UAAU,GAAC,UAAU,GAAC,SAAS,CAAC;IAAA,UAAU,EAAC,MAAM,CAAA;CAAC;AACvH,qBAAa,aAAa;IAAa,OAAO,CAAC,OAAO;IAAI,OAAO,CAAC,OAAO;gBAA1B,OAAO,SAAG,EAAS,OAAO,GAAC,OAAO,KAAW;YAAiB,IAAI;IAA+R,MAAM,CAAC,QAAQ,EAAC,eAAe;IAA4F,IAAI,CAAC,aAAa,EAAC,MAAM;kBAA6B,OAAO,EAAE;;IAAuE,GAAG,CAAC,EAAE,EAAC,MAAM;IAAsE,MAAM,CAAC,EAAE,EAAC,MAAM;IAA6F,OAAO,CAAC,EAAE,EAAC,MAAM,EAAC,aAAa,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM;IAA8J,IAAI,CAAC,SAAS,EAAC,MAAM,EAAC,WAAW,EAAC,MAAM,EAAC,cAAc,CAAC,EAAC,MAAM;IAA2J,MAAM,CAAC,IAAI,EAAC,OAAO;IAA2F,MAAM,CAAC,EAAE,EAAC,MAAM;IAAyE,MAAM,CAAC,EAAE,EAAC,MAAM;IAAgF,IAAI,CAAC,EAAE,EAAC,MAAM;CAA+F"}
|
package/dist/release.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class ReleaseClient {
|
|
2
|
+
constructor(baseUrl = '', fetcher = fetch) {
|
|
3
|
+
this.baseUrl = baseUrl;
|
|
4
|
+
this.fetcher = fetcher;
|
|
5
|
+
}
|
|
6
|
+
async json(path, init) { const r = await this.fetcher(`${this.baseUrl}${path}`, { credentials: 'include', headers: { 'content-type': 'application/json' }, ...init }); const v = await r.json(); if (!r.ok)
|
|
7
|
+
throw new Error(v?.error || `Release request failed (${r.status})`); return v; }
|
|
8
|
+
create(manifest) { return this.json('/v1/releases', { method: 'POST', body: JSON.stringify({ manifest }) }); }
|
|
9
|
+
list(applicationId) { return this.json(`/v1/releases?application_id=${encodeURIComponent(applicationId)}`); }
|
|
10
|
+
get(id) { return this.json(`/v1/releases/${encodeURIComponent(id)}`); }
|
|
11
|
+
verify(id) { return this.json(`/v1/releases/${encodeURIComponent(id)}/verify`, { method: 'POST' }); }
|
|
12
|
+
promote(id, applicationId, environment) { return this.json(`/v1/releases/${encodeURIComponent(id)}/promote`, { method: 'POST', body: JSON.stringify({ application_id: applicationId, environment }) }); }
|
|
13
|
+
plan(releaseId, environment, rollbackTarget) { return this.json('/v1/deployments/plan', { method: 'POST', body: JSON.stringify({ release_id: releaseId, environment, rollback_target: rollbackTarget }) }); }
|
|
14
|
+
deploy(plan) { return this.json('/v1/deployments', { method: 'POST', body: JSON.stringify({ plan }) }); }
|
|
15
|
+
status(id) { return this.json(`/v1/deployments/${encodeURIComponent(id)}`); }
|
|
16
|
+
health(id) { return this.json(`/v1/deployments/${encodeURIComponent(id)}/health`); }
|
|
17
|
+
stop(id) { return this.json(`/v1/deployments/${encodeURIComponent(id)}/stop`, { method: 'POST' }); }
|
|
18
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sharding - Horizontal data partitioning for scaling
|
|
3
|
+
*
|
|
4
|
+
* Distributes data across shards for linear scalability:
|
|
5
|
+
* - Consistent hashing for automatic shard assignment
|
|
6
|
+
* - Hotspot detection based on metrics
|
|
7
|
+
* - Automatic rebalancing recommendations
|
|
8
|
+
* - Multi-shard query support
|
|
9
|
+
*/
|
|
10
|
+
export type ShardingStrategy = 'consistent-hash' | 'range-based' | 'key-modulo';
|
|
11
|
+
export interface ShardKey {
|
|
12
|
+
field: string;
|
|
13
|
+
hashFunction: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ShardRange {
|
|
16
|
+
shardId: string;
|
|
17
|
+
startHash: number;
|
|
18
|
+
endHash: number;
|
|
19
|
+
replicaNodes: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ShardMetrics {
|
|
22
|
+
shardId: string;
|
|
23
|
+
entryCount: number;
|
|
24
|
+
sizeBytes: number;
|
|
25
|
+
reads: number;
|
|
26
|
+
writes: number;
|
|
27
|
+
avgQueryTimeMs: number;
|
|
28
|
+
}
|
|
29
|
+
export interface HotspotAlert {
|
|
30
|
+
shardId: string;
|
|
31
|
+
reason: string;
|
|
32
|
+
metricValue: number;
|
|
33
|
+
threshold: number;
|
|
34
|
+
severity: 'low' | 'medium' | 'high';
|
|
35
|
+
}
|
|
36
|
+
export interface RebalanceOperation {
|
|
37
|
+
sourceShard: string;
|
|
38
|
+
targetShard: string;
|
|
39
|
+
keyRangeStart: number;
|
|
40
|
+
keyRangeEnd: number;
|
|
41
|
+
estimatedRecords: number;
|
|
42
|
+
priority: number;
|
|
43
|
+
}
|
|
44
|
+
export interface ShardDistributionSummary {
|
|
45
|
+
numShards: number;
|
|
46
|
+
totalEntries: number;
|
|
47
|
+
totalSizeBytes: number;
|
|
48
|
+
totalReads: number;
|
|
49
|
+
totalWrites: number;
|
|
50
|
+
maxEntriesPerShard: number;
|
|
51
|
+
minEntriesPerShard: number;
|
|
52
|
+
imbalanceRatio: number;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Shard Manager - TypeScript implementation
|
|
56
|
+
*/
|
|
57
|
+
export declare class ShardManager {
|
|
58
|
+
private shardingKey;
|
|
59
|
+
private strategy;
|
|
60
|
+
private shardRanges;
|
|
61
|
+
private shardMetrics;
|
|
62
|
+
private rebalanceHistory;
|
|
63
|
+
private rebalanceThreshold;
|
|
64
|
+
constructor(shardingKey: ShardKey, strategy?: ShardingStrategy);
|
|
65
|
+
/**
|
|
66
|
+
* Hash a value using simple algorithm
|
|
67
|
+
*/
|
|
68
|
+
private hashValue;
|
|
69
|
+
/**
|
|
70
|
+
* Initialize shards
|
|
71
|
+
*/
|
|
72
|
+
initializeShards(shardIds: string[], replicaNodes?: Record<string, string[]>): void;
|
|
73
|
+
/**
|
|
74
|
+
* Get shard for a key
|
|
75
|
+
*/
|
|
76
|
+
getShardForKey(key: string): ShardRange | null;
|
|
77
|
+
/**
|
|
78
|
+
* Get replica nodes for a key
|
|
79
|
+
*/
|
|
80
|
+
getReplicasForKey(key: string): string[];
|
|
81
|
+
/**
|
|
82
|
+
* Record a shard operation
|
|
83
|
+
*/
|
|
84
|
+
recordShardOperation(shardId: string, operation: 'read' | 'write' | 'delete', timeMs: number, recordsAffected: number, sizeBytes: number): void;
|
|
85
|
+
/**
|
|
86
|
+
* Get all shard metrics
|
|
87
|
+
*/
|
|
88
|
+
getAllMetrics(): ShardMetrics[];
|
|
89
|
+
/**
|
|
90
|
+
* Detect hotspots
|
|
91
|
+
*/
|
|
92
|
+
detectHotspots(): HotspotAlert[];
|
|
93
|
+
/**
|
|
94
|
+
* Generate rebalance operations
|
|
95
|
+
*/
|
|
96
|
+
generateRebalanceOps(): RebalanceOperation[];
|
|
97
|
+
/**
|
|
98
|
+
* Get distribution summary
|
|
99
|
+
*/
|
|
100
|
+
getDistributionSummary(): ShardDistributionSummary;
|
|
101
|
+
/**
|
|
102
|
+
* Record a rebalance operation
|
|
103
|
+
*/
|
|
104
|
+
recordRebalance(operation: RebalanceOperation): void;
|
|
105
|
+
/**
|
|
106
|
+
* Get rebalance history
|
|
107
|
+
*/
|
|
108
|
+
getRebalanceHistory(): RebalanceOperation[];
|
|
109
|
+
/**
|
|
110
|
+
* Calculate standard deviation
|
|
111
|
+
*/
|
|
112
|
+
private calculateStdDev;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Shard Router - Routes queries to appropriate shards
|
|
116
|
+
*/
|
|
117
|
+
export declare class ShardRouter {
|
|
118
|
+
private shardManager;
|
|
119
|
+
private shardConnections;
|
|
120
|
+
constructor(shardManager: ShardManager);
|
|
121
|
+
/**
|
|
122
|
+
* Route a query to appropriate shards
|
|
123
|
+
*/
|
|
124
|
+
routeQuery(key: string): string[];
|
|
125
|
+
/**
|
|
126
|
+
* Route a range query to multiple shards
|
|
127
|
+
*/
|
|
128
|
+
routeRangeQuery(keyPattern: string): string[];
|
|
129
|
+
/**
|
|
130
|
+
* Register shard connection
|
|
131
|
+
*/
|
|
132
|
+
registerShardConnection(shardId: string, connection: any): void;
|
|
133
|
+
/**
|
|
134
|
+
* Get shard connection
|
|
135
|
+
*/
|
|
136
|
+
getShardConnection(shardId: string): any;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Rebalancer - Coordinates data migration between shards
|
|
140
|
+
*/
|
|
141
|
+
export declare class Rebalancer {
|
|
142
|
+
private shardManager;
|
|
143
|
+
private shardRouter;
|
|
144
|
+
private rebalanceInProgress;
|
|
145
|
+
constructor(shardManager: ShardManager, shardRouter: ShardRouter);
|
|
146
|
+
/**
|
|
147
|
+
* Start automatic rebalancing
|
|
148
|
+
*/
|
|
149
|
+
startAutoRebalance(intervalMs?: number): Promise<void>;
|
|
150
|
+
/**
|
|
151
|
+
* Perform rebalancing
|
|
152
|
+
*/
|
|
153
|
+
performRebalance(): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Check if rebalancing is needed
|
|
156
|
+
*/
|
|
157
|
+
isRebalanceNeeded(): boolean;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=sharding.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sharding.d.ts","sourceRoot":"","sources":["../src/sharding.ts"],"names":[],"mappings":"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"}
|