@feltdb/core 0.4.4 → 0.4.6
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 +22 -0
- package/bin/create-feltdb.js +3 -0
- package/bin/feltdb.js +3 -0
- package/dist/analytics-backend.js +1 -1
- package/dist/cli/api-client.js +236 -0
- package/dist/cli/cli.js +18 -0
- package/dist/cli/commands.js +795 -0
- package/dist/cli/config.js +66 -0
- package/dist/cli/index.js +399 -0
- package/dist/create/application-identity.js +132 -0
- package/dist/create/cli-scripts-generator.js +211 -0
- package/dist/create/cli.js +202 -0
- package/dist/create/create.js +638 -0
- package/dist/create/docker-compose-generator.js +258 -0
- package/dist/create/index.js +4 -0
- package/dist/create/package-versions.js +4 -0
- package/dist/create/runtime-templates.js +272 -0
- package/dist/index-backend.js +1 -1
- package/dist/migrate/analyzer/index.d.ts +2 -0
- package/dist/migrate/analyzer/index.js +34 -0
- package/dist/migrate/benchmark/index.d.ts +13 -0
- package/dist/migrate/benchmark/index.js +8 -0
- package/dist/migrate/capability-gate/index.d.ts +3 -0
- package/dist/migrate/capability-gate/index.js +3 -0
- package/dist/migrate/classifier/index.d.ts +3 -0
- package/dist/migrate/classifier/index.js +53 -0
- package/dist/migrate/cli/index.d.ts +2 -0
- package/dist/migrate/cli/index.js +201 -0
- package/dist/migrate/domain-model/index.d.ts +2 -0
- package/dist/migrate/domain-model/index.js +4 -0
- package/dist/migrate/generator/index.d.ts +2 -0
- package/dist/migrate/generator/index.js +21 -0
- package/dist/migrate/index.d.ts +16 -0
- package/dist/migrate/index.js +16 -0
- package/dist/migrate/measurement/index.d.ts +7 -0
- package/dist/migrate/measurement/index.js +1 -0
- package/dist/migrate/migrator/index.d.ts +2 -0
- package/dist/migrate/migrator/index.js +35 -0
- package/dist/migrate/planner/index.d.ts +2 -0
- package/dist/migrate/planner/index.js +12 -0
- package/dist/migrate/prover/index.d.ts +9 -0
- package/dist/migrate/prover/index.js +3 -0
- package/dist/migrate/reporter/index.d.ts +4 -0
- package/dist/migrate/reporter/index.js +1 -0
- package/dist/migrate/runtime-dependencies/index.d.ts +13 -0
- package/dist/migrate/runtime-dependencies/index.js +112 -0
- package/dist/migrate/state-contract/index.d.ts +13 -0
- package/dist/migrate/state-contract/index.js +49 -0
- package/dist/migrate/types/index.d.ts +228 -0
- package/dist/migrate/types/index.js +1 -0
- package/dist/migrate/ui-wiring/index.d.ts +18 -0
- package/dist/migrate/ui-wiring/index.js +2 -0
- package/dist/migrate/util.d.ts +5 -0
- package/dist/migrate/util.js +10 -0
- package/dist/react/index.d.ts +7 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +6 -0
- package/dist/react/useCapability.d.ts +11 -0
- package/dist/react/useCapability.d.ts.map +1 -0
- package/dist/react/useCapability.js +30 -0
- package/dist/react/useCollection.d.ts +17 -0
- package/dist/react/useCollection.d.ts.map +1 -0
- package/dist/react/useCollection.js +69 -0
- package/dist/react/useFeltDB.d.ts +136 -0
- package/dist/react/useFeltDB.d.ts.map +1 -0
- package/dist/react/useFeltDB.js +350 -0
- package/dist/studio/.gitkeep +1 -0
- package/dist/studio/KeyManagementPanel-BOvWTRyH.js +246 -0
- package/dist/studio/app.d.ts +10 -0
- package/dist/studio/app.d.ts.map +1 -0
- package/dist/studio/components/AgentExplorer.d.ts +9 -0
- package/dist/studio/components/AgentExplorer.d.ts.map +1 -0
- package/dist/studio/components/ApplicationDesigner.d.ts +11 -0
- package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -0
- package/dist/studio/components/CapabilityExplorer.d.ts +9 -0
- package/dist/studio/components/CapabilityExplorer.d.ts.map +1 -0
- package/dist/studio/components/ConflictExplorer.d.ts +9 -0
- package/dist/studio/components/ConflictExplorer.d.ts.map +1 -0
- package/dist/studio/components/ExecutionViewer.d.ts +9 -0
- package/dist/studio/components/ExecutionViewer.d.ts.map +1 -0
- package/dist/studio/components/GlobalSearch.d.ts +10 -0
- package/dist/studio/components/GlobalSearch.d.ts.map +1 -0
- package/dist/studio/components/HealthCenter.d.ts +9 -0
- package/dist/studio/components/HealthCenter.d.ts.map +1 -0
- package/dist/studio/components/KeyManagementPanel.d.ts +9 -0
- package/dist/studio/components/KeyManagementPanel.d.ts.map +1 -0
- package/dist/studio/components/KeyManagementPanel.js +2 -0
- package/dist/studio/components/ManagedInstancePanel.d.ts +4 -0
- package/dist/studio/components/ManagedInstancePanel.d.ts.map +1 -0
- package/dist/studio/components/ManagedInstancePanel.js +281 -0
- package/dist/studio/components/OperationsExplorer.d.ts +10 -0
- package/dist/studio/components/OperationsExplorer.d.ts.map +1 -0
- package/dist/studio/components/OverviewDashboard.d.ts +8 -0
- package/dist/studio/components/OverviewDashboard.d.ts.map +1 -0
- package/dist/studio/components/PeerMap.d.ts +8 -0
- package/dist/studio/components/PeerMap.d.ts.map +1 -0
- package/dist/studio/components/ProvenanceViewer.d.ts +11 -0
- package/dist/studio/components/ProvenanceViewer.d.ts.map +1 -0
- package/dist/studio/components/ReferenceExplorer.d.ts +10 -0
- package/dist/studio/components/ReferenceExplorer.d.ts.map +1 -0
- package/dist/studio/components/SettingsPanel.d.ts +7 -0
- package/dist/studio/components/SettingsPanel.d.ts.map +1 -0
- package/dist/studio/components/StateExplorer.d.ts +10 -0
- package/dist/studio/components/StateExplorer.d.ts.map +1 -0
- package/dist/studio/components/WorkflowVisualizer.d.ts +9 -0
- package/dist/studio/components/WorkflowVisualizer.d.ts.map +1 -0
- package/dist/studio/components/index.d.ts +24 -0
- package/dist/studio/components/index.d.ts.map +1 -0
- package/dist/studio/components/index.js +4 -0
- package/dist/studio/components-BRYUceo9.js +1711 -0
- package/dist/studio/hooks/index.d.ts +37 -0
- package/dist/studio/hooks/index.d.ts.map +1 -0
- package/dist/studio/index.d.ts +27 -0
- package/dist/studio/index.d.ts.map +1 -0
- package/dist/studio/index.html +30 -0
- package/dist/studio/index.js +236 -0
- package/dist/studio/main.d.ts +1 -0
- package/dist/studio/main.d.ts.map +1 -0
- package/dist/studio/studio.css +2 -0
- package/dist/studio/types/index.d.ts +133 -0
- package/dist/studio/types/index.d.ts.map +1 -0
- package/dist/studio/utils/api.d.ts +27 -0
- package/dist/studio/utils/api.d.ts.map +1 -0
- package/dist/studio/utils/format.d.ts +24 -0
- package/dist/studio/utils/format.d.ts.map +1 -0
- package/dist/studio/utils/index.d.ts +7 -0
- package/dist/studio/utils/index.d.ts.map +1 -0
- package/dist/studio/utils/index.js +75 -0
- package/dist/studio/utils/managed-instance.d.ts +40 -0
- package/dist/studio/utils/managed-instance.d.ts.map +1 -0
- package/dist/studio/utils/managed-instance.js +51 -0
- package/dist/studio-app/.gitkeep +1 -0
- package/dist/studio-app/assets/feltdb_wasm-BXMn9UxO.js +1 -0
- package/dist/studio-app/assets/feltdb_wasm_bg-bYYbZeRM.wasm +0 -0
- package/dist/studio-app/assets/index-B-lZjdtI.js +28 -0
- package/dist/studio-app/assets/index-CB-Eed9V.css +1 -0
- package/dist/studio-app/index.html +3 -0
- package/dist/wasm/feltdb_wasm.d.ts +461 -0
- package/dist/wasm/feltdb_wasm.js +1690 -0
- package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
- package/dist/wasm/feltdb_wasm_bg.wasm.d.ts +84 -0
- package/dist/wasm/package.json +16 -0
- package/package.json +40 -5
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
export declare const CLASSIFICATIONS: readonly ["STATE", "HISTORY", "RELATIONSHIP", "MATERIALIZED", "BLOB_REFERENCE", "SECRET_REFERENCE", "EXTERNAL_STATE", "OPERATIONAL", "REMOVE"];
|
|
2
|
+
export type Classification = typeof CLASSIFICATIONS[number];
|
|
3
|
+
export type Readiness = 'NEW' | 'ANALYZED' | 'CLASSIFIED' | 'APPROVED' | 'CAPABILITY_READY' | 'PLAN_READY' | 'GENERATED' | 'MIGRATED' | 'STATE_CONTRACT_READY' | 'UI_WIRING_READY' | 'POSTGRES_RUNTIME_FREE' | 'PROVEN' | 'BENCHMARKED' | 'CUTOVER_READY' | 'CUTOVER_COMPLETE';
|
|
4
|
+
export interface Column {
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
nullable?: boolean;
|
|
8
|
+
default?: string | null;
|
|
9
|
+
primaryKey?: boolean;
|
|
10
|
+
unique?: boolean;
|
|
11
|
+
sizeBytes?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface ForeignKey {
|
|
14
|
+
columns: string[];
|
|
15
|
+
referencedTable: string;
|
|
16
|
+
referencedColumns: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface Entity {
|
|
19
|
+
name: string;
|
|
20
|
+
columns: Column[];
|
|
21
|
+
primaryKey?: string[];
|
|
22
|
+
foreignKeys?: ForeignKey[];
|
|
23
|
+
indexes?: Array<{
|
|
24
|
+
name: string;
|
|
25
|
+
columns: string[];
|
|
26
|
+
unique?: boolean;
|
|
27
|
+
}>;
|
|
28
|
+
kind?: 'table' | 'view';
|
|
29
|
+
}
|
|
30
|
+
export interface SourceFinding {
|
|
31
|
+
file: string;
|
|
32
|
+
line: number;
|
|
33
|
+
kind: string;
|
|
34
|
+
value: string;
|
|
35
|
+
entities: string[];
|
|
36
|
+
}
|
|
37
|
+
export interface Analysis {
|
|
38
|
+
version: 1;
|
|
39
|
+
generatedAt: string;
|
|
40
|
+
sourceRoot: string;
|
|
41
|
+
entities: Entity[];
|
|
42
|
+
findings: SourceFinding[];
|
|
43
|
+
dependencies: Array<{
|
|
44
|
+
from: string;
|
|
45
|
+
to: string;
|
|
46
|
+
}>;
|
|
47
|
+
schemaHash: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ClassifiedEntity {
|
|
50
|
+
entity: string;
|
|
51
|
+
classification: Classification;
|
|
52
|
+
confidence: number;
|
|
53
|
+
reasons: string[];
|
|
54
|
+
requiresApproval: boolean;
|
|
55
|
+
}
|
|
56
|
+
export interface ClassificationResult {
|
|
57
|
+
version: 1;
|
|
58
|
+
threshold: number;
|
|
59
|
+
entities: ClassifiedEntity[];
|
|
60
|
+
classificationHash: string;
|
|
61
|
+
approved: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface DomainEntity extends ClassifiedEntity {
|
|
64
|
+
authoritative: boolean;
|
|
65
|
+
target: string;
|
|
66
|
+
secretColumns: string[];
|
|
67
|
+
blobColumns: string[];
|
|
68
|
+
}
|
|
69
|
+
export interface DomainModel {
|
|
70
|
+
version: 1;
|
|
71
|
+
entities: DomainEntity[];
|
|
72
|
+
hash: string;
|
|
73
|
+
}
|
|
74
|
+
export interface PlanStep {
|
|
75
|
+
id: string;
|
|
76
|
+
entity: string;
|
|
77
|
+
classification: Classification;
|
|
78
|
+
dependsOn: string[];
|
|
79
|
+
order: number;
|
|
80
|
+
tenantKey?: string;
|
|
81
|
+
}
|
|
82
|
+
export interface MigrationPlan {
|
|
83
|
+
version: 1;
|
|
84
|
+
planHash: string;
|
|
85
|
+
steps: PlanStep[];
|
|
86
|
+
}
|
|
87
|
+
export interface StateConsumer {
|
|
88
|
+
id: string;
|
|
89
|
+
file: string;
|
|
90
|
+
line: number;
|
|
91
|
+
surface: string;
|
|
92
|
+
semantic: string;
|
|
93
|
+
source: 'legacy' | 'canonical' | 'unknown';
|
|
94
|
+
endpoint?: string;
|
|
95
|
+
}
|
|
96
|
+
export interface StateDomain {
|
|
97
|
+
name: string;
|
|
98
|
+
authoritativeState: string;
|
|
99
|
+
history?: string;
|
|
100
|
+
fields: Record<string, {
|
|
101
|
+
source: string;
|
|
102
|
+
canonical: string;
|
|
103
|
+
}>;
|
|
104
|
+
uiSurfaces: string[];
|
|
105
|
+
lifecycleStates: string[];
|
|
106
|
+
emptyWhen: string;
|
|
107
|
+
refresh: 'subscription' | 'poll' | 'request';
|
|
108
|
+
tenantKey?: string;
|
|
109
|
+
}
|
|
110
|
+
export interface StateContract {
|
|
111
|
+
contractVersion: '1.0';
|
|
112
|
+
contractHash: string;
|
|
113
|
+
generatedAt: string;
|
|
114
|
+
domains: StateDomain[];
|
|
115
|
+
consumers: StateConsumer[];
|
|
116
|
+
legacyConsumers: number;
|
|
117
|
+
canonicalConsumers: number;
|
|
118
|
+
unresolved: string[];
|
|
119
|
+
}
|
|
120
|
+
export interface Capabilities {
|
|
121
|
+
[name: string]: boolean;
|
|
122
|
+
}
|
|
123
|
+
export interface Checkpoint {
|
|
124
|
+
stepId: string;
|
|
125
|
+
status: 'pending' | 'running' | 'complete' | 'failed';
|
|
126
|
+
cursor?: string;
|
|
127
|
+
records: number;
|
|
128
|
+
error?: string;
|
|
129
|
+
}
|
|
130
|
+
export interface MigrationTelemetry {
|
|
131
|
+
timestamp: string;
|
|
132
|
+
stepId: string;
|
|
133
|
+
operation: string;
|
|
134
|
+
records: number;
|
|
135
|
+
durationMs: number;
|
|
136
|
+
tenant?: string;
|
|
137
|
+
}
|
|
138
|
+
export interface MigrationAdapter {
|
|
139
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
140
|
+
put(collection: string, id: string, value: unknown, options: {
|
|
141
|
+
idempotencyKey: string;
|
|
142
|
+
tenant?: string;
|
|
143
|
+
}): Promise<void>;
|
|
144
|
+
append(collection: string, id: string, value: unknown, options: {
|
|
145
|
+
idempotencyKey: string;
|
|
146
|
+
tenant?: string;
|
|
147
|
+
}): Promise<void>;
|
|
148
|
+
relate(collection: string, from: string, to: string, options: {
|
|
149
|
+
idempotencyKey: string;
|
|
150
|
+
tenant?: string;
|
|
151
|
+
}): Promise<void>;
|
|
152
|
+
}
|
|
153
|
+
export interface SourceAdapter {
|
|
154
|
+
read(entity: string, cursor?: string, tenant?: string): AsyncIterable<{
|
|
155
|
+
id: string;
|
|
156
|
+
value: Record<string, unknown>;
|
|
157
|
+
cursor?: string;
|
|
158
|
+
}>;
|
|
159
|
+
}
|
|
160
|
+
export interface FeltDBRuntimeContract {
|
|
161
|
+
mode: 'browser' | 'node' | 'self-hosted' | 'managed';
|
|
162
|
+
requiredEnvironment: string[];
|
|
163
|
+
healthCheck?: string;
|
|
164
|
+
persistence?: string;
|
|
165
|
+
}
|
|
166
|
+
export type DependencyClassification = 'RUNTIME' | 'MIGRATION_SOURCE' | 'LEGACY_FALLBACK' | 'TEST_ONLY' | 'BUILD_ONLY' | 'DEVELOPMENT_ONLY' | 'ROLLBACK_ONLY';
|
|
167
|
+
export type RuntimeFindingCode = 'POSTGRES_RUNTIME_CONNECTION' | 'POSTGRES_RUNTIME_ENV' | 'POSTGRES_RUNTIME_URL' | 'POSTGRES_RUNTIME_CLIENT' | 'POSTGRES_RUNTIME_SQL' | 'POSTGRES_RUNTIME_STARTUP_DEPENDENCY' | 'POSTGRES_RUNTIME_HEALTHCHECK' | 'POSTGRES_RUNTIME_CONTAINER' | 'POSTGRES_RUNTIME_DEPLOYMENT_DEPENDENCY';
|
|
168
|
+
export interface RuntimeDependencyFinding {
|
|
169
|
+
id: string;
|
|
170
|
+
code: RuntimeFindingCode;
|
|
171
|
+
file: string;
|
|
172
|
+
line: number;
|
|
173
|
+
classification: DependencyClassification;
|
|
174
|
+
runtime: boolean;
|
|
175
|
+
kind: 'environment' | 'connection' | 'sql' | 'startup' | 'healthcheck' | 'container' | 'deployment' | 'dependency';
|
|
176
|
+
evidence: string;
|
|
177
|
+
action: string;
|
|
178
|
+
}
|
|
179
|
+
export interface PostgresDependencyManifest {
|
|
180
|
+
version: 1;
|
|
181
|
+
generatedAt: string;
|
|
182
|
+
sourceRoot: string;
|
|
183
|
+
findings: RuntimeDependencyFinding[];
|
|
184
|
+
runtime: RuntimeDependencyFinding[];
|
|
185
|
+
migrationSource: RuntimeDependencyFinding[];
|
|
186
|
+
legacyFallback: RuntimeDependencyFinding[];
|
|
187
|
+
testOnly: RuntimeDependencyFinding[];
|
|
188
|
+
developmentOnly: RuntimeDependencyFinding[];
|
|
189
|
+
buildOnly: RuntimeDependencyFinding[];
|
|
190
|
+
rollbackOnly: RuntimeDependencyFinding[];
|
|
191
|
+
runtimeDependencyHash: string;
|
|
192
|
+
feltDbRuntime: FeltDBRuntimeContract;
|
|
193
|
+
}
|
|
194
|
+
export interface RuntimeDependencyProof {
|
|
195
|
+
postgresRuntimeDependency: boolean;
|
|
196
|
+
postgresConnections: number;
|
|
197
|
+
postgresSqlExecutions: number;
|
|
198
|
+
postgresEnvironmentVariables: number;
|
|
199
|
+
postgresStartupDependencies: number;
|
|
200
|
+
postgresHealthChecks: number;
|
|
201
|
+
postgresRuntimeContainers: number;
|
|
202
|
+
postgresRuntimeDeploymentReferences: number;
|
|
203
|
+
feltDbRuntime: boolean;
|
|
204
|
+
verifiedWithoutPostgres: boolean;
|
|
205
|
+
startupVerified: boolean;
|
|
206
|
+
recoveryVerified: boolean;
|
|
207
|
+
networkIsolationVerified: boolean;
|
|
208
|
+
runtimeDependencyHash: string;
|
|
209
|
+
}
|
|
210
|
+
export interface SherpaConfig {
|
|
211
|
+
sourceRoot: string;
|
|
212
|
+
artifactDir?: string;
|
|
213
|
+
schemaFile: string;
|
|
214
|
+
confidenceThreshold?: number;
|
|
215
|
+
classificationOverrides?: Record<string, Classification>;
|
|
216
|
+
tenantKeys?: Record<string, string>;
|
|
217
|
+
capabilities?: Capabilities;
|
|
218
|
+
requiredCapabilities?: string[];
|
|
219
|
+
stateDomains?: Array<Partial<StateDomain> & {
|
|
220
|
+
name: string;
|
|
221
|
+
authoritativeState: string;
|
|
222
|
+
}>;
|
|
223
|
+
strictStateContract?: boolean;
|
|
224
|
+
blobThresholdBytes?: number;
|
|
225
|
+
feltDbRuntime?: FeltDBRuntimeContract;
|
|
226
|
+
runtimeDependencyOverrides?: Record<string, DependencyClassification>;
|
|
227
|
+
runtimeVerificationModule?: string;
|
|
228
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CLASSIFICATIONS = ['STATE', 'HISTORY', 'RELATIONSHIP', 'MATERIALIZED', 'BLOB_REFERENCE', 'SECRET_REFERENCE', 'EXTERNAL_STATE', 'OPERATIONAL', 'REMOVE'];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StateContract } from '../types/index.js';
|
|
2
|
+
export interface CanonicalStateReader {
|
|
3
|
+
state(domain: string, id: string): Promise<Record<string, unknown> | undefined>;
|
|
4
|
+
history(domain: string, id: string): Promise<unknown[]>;
|
|
5
|
+
relationships?(domain: string, id: string): Promise<unknown[]>;
|
|
6
|
+
}
|
|
7
|
+
export declare function createCanonicalAdapter(contract: StateContract, reader: CanonicalStateReader): {
|
|
8
|
+
read(domainName: string, id: string): Promise<{
|
|
9
|
+
status: unknown;
|
|
10
|
+
currentAction: unknown;
|
|
11
|
+
plan: unknown;
|
|
12
|
+
activity: unknown[];
|
|
13
|
+
history: unknown[];
|
|
14
|
+
result: unknown;
|
|
15
|
+
relationships: unknown[];
|
|
16
|
+
empty: boolean;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export function createCanonicalAdapter(contract, reader) { return { async read(domainName, id) { const domain = contract.domains.find(d => d.name === domainName); if (!domain)
|
|
2
|
+
throw new Error(`Unknown canonical domain: ${domainName}`); const [state, history, relationships] = await Promise.all([reader.state(domain.authoritativeState, id), domain.history ? reader.history(domain.history, id) : Promise.resolve([]), reader.relationships?.(domainName, id) ?? Promise.resolve([])]); return { status: state?.status, currentAction: state?.currentAction, plan: state?.plan, activity: history, history, result: state?.result, relationships, empty: !state && history.length === 0 }; } }; }
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function stable(value: unknown): string;
|
|
2
|
+
export declare function hash(value: unknown): string;
|
|
3
|
+
export declare function json<T>(file: string): Promise<T>;
|
|
4
|
+
export declare function writeJson(file: string, value: unknown): Promise<void>;
|
|
5
|
+
export declare const artifact: (dir: string, name: string) => string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
export function stable(value) { if (Array.isArray(value))
|
|
5
|
+
return `[${value.map(stable).join(',')}]`; if (value && typeof value === 'object')
|
|
6
|
+
return `{${Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => `${JSON.stringify(k)}:${stable(v)}`).join(',')}}`; return JSON.stringify(value); }
|
|
7
|
+
export function hash(value) { return createHash('sha256').update(stable(value)).digest('hex'); }
|
|
8
|
+
export async function json(file) { return JSON.parse(await readFile(file, 'utf8')); }
|
|
9
|
+
export async function writeJson(file, value) { await mkdir(dirname(file), { recursive: true }); await writeFile(file, JSON.stringify(value, null, 2) + '\n'); }
|
|
10
|
+
export const artifact = (dir, name) => join(dir, name);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,gBAAgB,CAAC;AAC/B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for executing FeltDB capabilities
|
|
3
|
+
*/
|
|
4
|
+
import type { Capability } from '@feltdb/core';
|
|
5
|
+
export declare function useCapability<TArgs extends any[] = any[], TResult = any>(capability: Capability | undefined): {
|
|
6
|
+
execute: (...args: TArgs) => Promise<any>;
|
|
7
|
+
loading: boolean;
|
|
8
|
+
error: Error | null;
|
|
9
|
+
result: TResult | null;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=useCapability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCapability.d.ts","sourceRoot":"","sources":["../src/useCapability.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,wBAAgB,aAAa,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,EAAE,EAAE,OAAO,GAAG,GAAG,EACtE,UAAU,EAAE,UAAU,GAAG,SAAS;uBAOhB,KAAK;;;;EAsBxB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for executing FeltDB capabilities
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback, useState } from 'react';
|
|
5
|
+
export function useCapability(capability) {
|
|
6
|
+
const [loading, setLoading] = useState(false);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
const [result, setResult] = useState(null);
|
|
9
|
+
const execute = useCallback(async (...args) => {
|
|
10
|
+
if (!capability) {
|
|
11
|
+
throw new Error('Capability not available');
|
|
12
|
+
}
|
|
13
|
+
setLoading(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
try {
|
|
16
|
+
const output = await capability.execute(...args);
|
|
17
|
+
setResult(output);
|
|
18
|
+
return output;
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
const error = err;
|
|
22
|
+
setError(error);
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
setLoading(false);
|
|
27
|
+
}
|
|
28
|
+
}, [capability]);
|
|
29
|
+
return { execute, loading, error, result };
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for interacting with FeltDB collections
|
|
3
|
+
*/
|
|
4
|
+
import type { Collection } from '@feltdb/core';
|
|
5
|
+
export interface UseCollectionOptions {
|
|
6
|
+
query?: any;
|
|
7
|
+
subscribe?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function useCollection<T = any>(collection: Collection<T>, options?: UseCollectionOptions): {
|
|
10
|
+
data: T[];
|
|
11
|
+
loading: boolean;
|
|
12
|
+
error: Error | null;
|
|
13
|
+
insert: (item: T) => Promise<void>;
|
|
14
|
+
update: (id: string, item: Partial<T>) => Promise<void>;
|
|
15
|
+
remove: (id: string) => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=useCollection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCollection.d.ts","sourceRoot":"","sources":["../src/useCollection.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,aAAa,CAAC,CAAC,GAAG,GAAG,EACnC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,EACzB,OAAO,CAAC,EAAE,oBAAoB;;;;mBA0Bf,CAAC;iBAaH,MAAM,QAAQ,OAAO,CAAC,CAAC,CAAC;iBAaxB,MAAM;EAapB"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook for interacting with FeltDB collections
|
|
3
|
+
*/
|
|
4
|
+
import { useCallback, useState, useEffect } from 'react';
|
|
5
|
+
export function useCollection(collection, options) {
|
|
6
|
+
const [data, setData] = useState([]);
|
|
7
|
+
const [loading, setLoading] = useState(false);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
let active = true;
|
|
11
|
+
setLoading(true);
|
|
12
|
+
collection
|
|
13
|
+
.find(options?.query || {})
|
|
14
|
+
.then((results) => {
|
|
15
|
+
if (active) {
|
|
16
|
+
setData(results);
|
|
17
|
+
setLoading(false);
|
|
18
|
+
}
|
|
19
|
+
})
|
|
20
|
+
.catch((err) => {
|
|
21
|
+
if (active) {
|
|
22
|
+
setError(err);
|
|
23
|
+
setLoading(false);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
const unsubscribe = options?.subscribe === false ? undefined : collection.subscribe(() => {
|
|
27
|
+
void collection.find(options?.query || {}).then(results => {
|
|
28
|
+
if (active) {
|
|
29
|
+
setData(results);
|
|
30
|
+
setError(null);
|
|
31
|
+
setLoading(false);
|
|
32
|
+
}
|
|
33
|
+
}).catch(err => { if (active)
|
|
34
|
+
setError(err); });
|
|
35
|
+
});
|
|
36
|
+
return () => { active = false; unsubscribe?.(); };
|
|
37
|
+
}, [collection, options?.query, options?.subscribe]);
|
|
38
|
+
const insert = useCallback(async (item) => {
|
|
39
|
+
try {
|
|
40
|
+
await collection.insert(item);
|
|
41
|
+
const updated = await collection.find(options?.query || {});
|
|
42
|
+
setData(updated);
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
setError(err);
|
|
46
|
+
}
|
|
47
|
+
}, [collection, options?.query]);
|
|
48
|
+
const update = useCallback(async (id, item) => {
|
|
49
|
+
try {
|
|
50
|
+
await collection.update(id, item);
|
|
51
|
+
const updated = await collection.find(options?.query || {});
|
|
52
|
+
setData(updated);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
setError(err);
|
|
56
|
+
}
|
|
57
|
+
}, [collection, options?.query]);
|
|
58
|
+
const remove = useCallback(async (id) => {
|
|
59
|
+
try {
|
|
60
|
+
await collection.delete(id);
|
|
61
|
+
const updated = await collection.find(options?.query || {});
|
|
62
|
+
setData(updated);
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
setError(err);
|
|
66
|
+
}
|
|
67
|
+
}, [collection, options?.query]);
|
|
68
|
+
return { data, loading, error, insert, update, remove };
|
|
69
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useFeltDB - React hook for FeltDB integration
|
|
3
|
+
*
|
|
4
|
+
* This module provides React hooks for easily integrating FeltDB
|
|
5
|
+
* into React applications with automatic state management.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* ```jsx
|
|
9
|
+
* import { useFeltDB } from './hooks/useFeltDB';
|
|
10
|
+
*
|
|
11
|
+
* function UserList() {
|
|
12
|
+
* const users = useFeltDB("users");
|
|
13
|
+
*
|
|
14
|
+
* const addUser = (name, email) => {
|
|
15
|
+
* users.insert(name, email);
|
|
16
|
+
* };
|
|
17
|
+
*
|
|
18
|
+
* return (
|
|
19
|
+
* <div>
|
|
20
|
+
* {users.records.map(user => (
|
|
21
|
+
* <div key={user.id}>{user.name}</div>
|
|
22
|
+
* ))}
|
|
23
|
+
* </div>
|
|
24
|
+
* );
|
|
25
|
+
* }
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
import type { JsDb } from '@feltdb/core/wasm';
|
|
29
|
+
import type { Collection } from '@feltdb/core';
|
|
30
|
+
interface UseFeltDBOptions {
|
|
31
|
+
/** Auto-refresh interval in milliseconds (0 to disable) */
|
|
32
|
+
refreshInterval?: number;
|
|
33
|
+
/** Callback when data updates */
|
|
34
|
+
onUpdate?: (records: any[]) => void;
|
|
35
|
+
/** Callback when error occurs */
|
|
36
|
+
onError?: (error: string) => void;
|
|
37
|
+
}
|
|
38
|
+
interface UseFeltDBResult<T = any> {
|
|
39
|
+
/** Array of records from the database */
|
|
40
|
+
records: T[];
|
|
41
|
+
/** Whether data is loading */
|
|
42
|
+
loading: boolean;
|
|
43
|
+
/** Error message if any */
|
|
44
|
+
error: string | null;
|
|
45
|
+
/** Insert a new record */
|
|
46
|
+
insert: (key: string, data: Record<string, any>) => boolean;
|
|
47
|
+
/** Get a single record by key */
|
|
48
|
+
get: (key: string) => any | null;
|
|
49
|
+
/** Refresh data manually */
|
|
50
|
+
refresh: () => void;
|
|
51
|
+
/** Update a record */
|
|
52
|
+
update: (id: string | number, changes: Partial<T>) => Promise<void>;
|
|
53
|
+
/** Delete a record */
|
|
54
|
+
delete: (id: string | number) => Promise<void>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* React hook for FeltDB state-first collections
|
|
58
|
+
*
|
|
59
|
+
* This is a thin adapter that bridges React state management with FeltDB's
|
|
60
|
+
* unified state model. All applications (React, Vue, Svelte) use the same
|
|
61
|
+
* underlying Collection semantics.
|
|
62
|
+
*
|
|
63
|
+
* @param collection A FeltDB Collection (live application state)
|
|
64
|
+
* @param options Configuration options
|
|
65
|
+
* @returns UseFeltDBResult with records and helper methods
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```jsx
|
|
69
|
+
* import { useFeltDB } from 'feltdb/useFeltDB';
|
|
70
|
+
*
|
|
71
|
+
* function UserList({ collection }) {
|
|
72
|
+
* const { records, loading, error, insert, update } = useFeltDB(collection);
|
|
73
|
+
*
|
|
74
|
+
* if (loading) return <div>Loading...</div>;
|
|
75
|
+
* if (error) return <div>Error: {error}</div>;
|
|
76
|
+
*
|
|
77
|
+
* return (
|
|
78
|
+
* <div>
|
|
79
|
+
* {records.map((user) => (
|
|
80
|
+
* <div key={user.id}>{user.name}</div>
|
|
81
|
+
* ))}
|
|
82
|
+
* </div>
|
|
83
|
+
* );
|
|
84
|
+
* }
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
87
|
+
export declare function useFeltDB<T = any>(collection: Collection<T> | null, options?: UseFeltDBOptions): UseFeltDBResult<T>;
|
|
88
|
+
/**
|
|
89
|
+
* Legacy compatibility: React hook for FeltDB capability queries
|
|
90
|
+
* Uses the low-level JsDb API for backward compatibility.
|
|
91
|
+
*
|
|
92
|
+
* New code should use useFeltDB with Collections instead.
|
|
93
|
+
*/
|
|
94
|
+
export declare function useLegacyFeltDB(db: JsDb | null, capability: string, options?: UseFeltDBOptions): UseFeltDBResult;
|
|
95
|
+
/**
|
|
96
|
+
* Higher-order component for wrapping components with FeltDB
|
|
97
|
+
*
|
|
98
|
+
* @param Component React component that receives db and useFeltDB hook
|
|
99
|
+
* @param dbPath Path to the database file
|
|
100
|
+
* @returns Wrapped component
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```jsx
|
|
104
|
+
* const UserListWithDb = withFeltDB(UserList, "app.db");
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export declare function withFeltDB<P extends object>(Component: React.ComponentType<P & {
|
|
108
|
+
db: JsDb;
|
|
109
|
+
}>, dbPath: string): React.FC<P>;
|
|
110
|
+
/**
|
|
111
|
+
* Example component using useFeltDB
|
|
112
|
+
*
|
|
113
|
+
* @example
|
|
114
|
+
* ```jsx
|
|
115
|
+
* import { useFeltDB } from './hooks/useFeltDB';
|
|
116
|
+
*
|
|
117
|
+
* function UserList({ db }) {
|
|
118
|
+
* const { records, loading, error, insert } = useFeltDB(db, "users", {
|
|
119
|
+
* refreshInterval: 5000, // Refresh every 5 seconds
|
|
120
|
+
* });
|
|
121
|
+
*
|
|
122
|
+
* if (loading) return <div>Loading...</div>;
|
|
123
|
+
* if (error) return <div>Error: {error}</div>;
|
|
124
|
+
*
|
|
125
|
+
* return (
|
|
126
|
+
* <div>
|
|
127
|
+
* {records.map((user: any) => (
|
|
128
|
+
* <div key={user.id}>{user.name} ({user.email})</div>
|
|
129
|
+
* ))}
|
|
130
|
+
* </div>
|
|
131
|
+
* );
|
|
132
|
+
* }
|
|
133
|
+
* ```
|
|
134
|
+
*/
|
|
135
|
+
export default useFeltDB;
|
|
136
|
+
//# sourceMappingURL=useFeltDB.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFeltDB.d.ts","sourceRoot":"","sources":["../src/useFeltDB.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,UAAU,gBAAgB;IACxB,2DAA2D;IAC3D,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IACpC,iCAAiC;IACjC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,UAAU,eAAe,CAAC,CAAC,GAAG,GAAG;IAC/B,yCAAyC;IACzC,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,8BAA8B;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,2BAA2B;IAC3B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0BAA0B;IAC1B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,OAAO,CAAC;IAC5D,iCAAiC;IACjC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC;IACjC,4BAA4B;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,sBAAsB;IACtB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,sBAAsB;IACtB,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,GAAG,EAC/B,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,IAAI,EAChC,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CAAC,CAAC,CAAC,CAiJpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,EAAE,EAAE,IAAI,GAAG,IAAI,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CA8GjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,MAAM,EACzC,SAAS,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,CAAC,EAChD,MAAM,EAAE,MAAM,GACb,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CA4Bb;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAe,SAAS,CAAC"}
|