@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.
Files changed (143) hide show
  1. package/README.md +22 -0
  2. package/bin/create-feltdb.js +3 -0
  3. package/bin/feltdb.js +3 -0
  4. package/dist/analytics-backend.js +1 -1
  5. package/dist/cli/api-client.js +236 -0
  6. package/dist/cli/cli.js +18 -0
  7. package/dist/cli/commands.js +795 -0
  8. package/dist/cli/config.js +66 -0
  9. package/dist/cli/index.js +399 -0
  10. package/dist/create/application-identity.js +132 -0
  11. package/dist/create/cli-scripts-generator.js +211 -0
  12. package/dist/create/cli.js +202 -0
  13. package/dist/create/create.js +638 -0
  14. package/dist/create/docker-compose-generator.js +258 -0
  15. package/dist/create/index.js +4 -0
  16. package/dist/create/package-versions.js +4 -0
  17. package/dist/create/runtime-templates.js +272 -0
  18. package/dist/index-backend.js +1 -1
  19. package/dist/migrate/analyzer/index.d.ts +2 -0
  20. package/dist/migrate/analyzer/index.js +34 -0
  21. package/dist/migrate/benchmark/index.d.ts +13 -0
  22. package/dist/migrate/benchmark/index.js +8 -0
  23. package/dist/migrate/capability-gate/index.d.ts +3 -0
  24. package/dist/migrate/capability-gate/index.js +3 -0
  25. package/dist/migrate/classifier/index.d.ts +3 -0
  26. package/dist/migrate/classifier/index.js +53 -0
  27. package/dist/migrate/cli/index.d.ts +2 -0
  28. package/dist/migrate/cli/index.js +201 -0
  29. package/dist/migrate/domain-model/index.d.ts +2 -0
  30. package/dist/migrate/domain-model/index.js +4 -0
  31. package/dist/migrate/generator/index.d.ts +2 -0
  32. package/dist/migrate/generator/index.js +21 -0
  33. package/dist/migrate/index.d.ts +16 -0
  34. package/dist/migrate/index.js +16 -0
  35. package/dist/migrate/measurement/index.d.ts +7 -0
  36. package/dist/migrate/measurement/index.js +1 -0
  37. package/dist/migrate/migrator/index.d.ts +2 -0
  38. package/dist/migrate/migrator/index.js +35 -0
  39. package/dist/migrate/planner/index.d.ts +2 -0
  40. package/dist/migrate/planner/index.js +12 -0
  41. package/dist/migrate/prover/index.d.ts +9 -0
  42. package/dist/migrate/prover/index.js +3 -0
  43. package/dist/migrate/reporter/index.d.ts +4 -0
  44. package/dist/migrate/reporter/index.js +1 -0
  45. package/dist/migrate/runtime-dependencies/index.d.ts +13 -0
  46. package/dist/migrate/runtime-dependencies/index.js +112 -0
  47. package/dist/migrate/state-contract/index.d.ts +13 -0
  48. package/dist/migrate/state-contract/index.js +49 -0
  49. package/dist/migrate/types/index.d.ts +228 -0
  50. package/dist/migrate/types/index.js +1 -0
  51. package/dist/migrate/ui-wiring/index.d.ts +18 -0
  52. package/dist/migrate/ui-wiring/index.js +2 -0
  53. package/dist/migrate/util.d.ts +5 -0
  54. package/dist/migrate/util.js +10 -0
  55. package/dist/react/index.d.ts +7 -0
  56. package/dist/react/index.d.ts.map +1 -0
  57. package/dist/react/index.js +6 -0
  58. package/dist/react/useCapability.d.ts +11 -0
  59. package/dist/react/useCapability.d.ts.map +1 -0
  60. package/dist/react/useCapability.js +30 -0
  61. package/dist/react/useCollection.d.ts +17 -0
  62. package/dist/react/useCollection.d.ts.map +1 -0
  63. package/dist/react/useCollection.js +69 -0
  64. package/dist/react/useFeltDB.d.ts +136 -0
  65. package/dist/react/useFeltDB.d.ts.map +1 -0
  66. package/dist/react/useFeltDB.js +350 -0
  67. package/dist/studio/.gitkeep +1 -0
  68. package/dist/studio/KeyManagementPanel-BOvWTRyH.js +246 -0
  69. package/dist/studio/app.d.ts +10 -0
  70. package/dist/studio/app.d.ts.map +1 -0
  71. package/dist/studio/components/AgentExplorer.d.ts +9 -0
  72. package/dist/studio/components/AgentExplorer.d.ts.map +1 -0
  73. package/dist/studio/components/ApplicationDesigner.d.ts +11 -0
  74. package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -0
  75. package/dist/studio/components/CapabilityExplorer.d.ts +9 -0
  76. package/dist/studio/components/CapabilityExplorer.d.ts.map +1 -0
  77. package/dist/studio/components/ConflictExplorer.d.ts +9 -0
  78. package/dist/studio/components/ConflictExplorer.d.ts.map +1 -0
  79. package/dist/studio/components/ExecutionViewer.d.ts +9 -0
  80. package/dist/studio/components/ExecutionViewer.d.ts.map +1 -0
  81. package/dist/studio/components/GlobalSearch.d.ts +10 -0
  82. package/dist/studio/components/GlobalSearch.d.ts.map +1 -0
  83. package/dist/studio/components/HealthCenter.d.ts +9 -0
  84. package/dist/studio/components/HealthCenter.d.ts.map +1 -0
  85. package/dist/studio/components/KeyManagementPanel.d.ts +9 -0
  86. package/dist/studio/components/KeyManagementPanel.d.ts.map +1 -0
  87. package/dist/studio/components/KeyManagementPanel.js +2 -0
  88. package/dist/studio/components/ManagedInstancePanel.d.ts +4 -0
  89. package/dist/studio/components/ManagedInstancePanel.d.ts.map +1 -0
  90. package/dist/studio/components/ManagedInstancePanel.js +281 -0
  91. package/dist/studio/components/OperationsExplorer.d.ts +10 -0
  92. package/dist/studio/components/OperationsExplorer.d.ts.map +1 -0
  93. package/dist/studio/components/OverviewDashboard.d.ts +8 -0
  94. package/dist/studio/components/OverviewDashboard.d.ts.map +1 -0
  95. package/dist/studio/components/PeerMap.d.ts +8 -0
  96. package/dist/studio/components/PeerMap.d.ts.map +1 -0
  97. package/dist/studio/components/ProvenanceViewer.d.ts +11 -0
  98. package/dist/studio/components/ProvenanceViewer.d.ts.map +1 -0
  99. package/dist/studio/components/ReferenceExplorer.d.ts +10 -0
  100. package/dist/studio/components/ReferenceExplorer.d.ts.map +1 -0
  101. package/dist/studio/components/SettingsPanel.d.ts +7 -0
  102. package/dist/studio/components/SettingsPanel.d.ts.map +1 -0
  103. package/dist/studio/components/StateExplorer.d.ts +10 -0
  104. package/dist/studio/components/StateExplorer.d.ts.map +1 -0
  105. package/dist/studio/components/WorkflowVisualizer.d.ts +9 -0
  106. package/dist/studio/components/WorkflowVisualizer.d.ts.map +1 -0
  107. package/dist/studio/components/index.d.ts +24 -0
  108. package/dist/studio/components/index.d.ts.map +1 -0
  109. package/dist/studio/components/index.js +4 -0
  110. package/dist/studio/components-BRYUceo9.js +1711 -0
  111. package/dist/studio/hooks/index.d.ts +37 -0
  112. package/dist/studio/hooks/index.d.ts.map +1 -0
  113. package/dist/studio/index.d.ts +27 -0
  114. package/dist/studio/index.d.ts.map +1 -0
  115. package/dist/studio/index.html +30 -0
  116. package/dist/studio/index.js +236 -0
  117. package/dist/studio/main.d.ts +1 -0
  118. package/dist/studio/main.d.ts.map +1 -0
  119. package/dist/studio/studio.css +2 -0
  120. package/dist/studio/types/index.d.ts +133 -0
  121. package/dist/studio/types/index.d.ts.map +1 -0
  122. package/dist/studio/utils/api.d.ts +27 -0
  123. package/dist/studio/utils/api.d.ts.map +1 -0
  124. package/dist/studio/utils/format.d.ts +24 -0
  125. package/dist/studio/utils/format.d.ts.map +1 -0
  126. package/dist/studio/utils/index.d.ts +7 -0
  127. package/dist/studio/utils/index.d.ts.map +1 -0
  128. package/dist/studio/utils/index.js +75 -0
  129. package/dist/studio/utils/managed-instance.d.ts +40 -0
  130. package/dist/studio/utils/managed-instance.d.ts.map +1 -0
  131. package/dist/studio/utils/managed-instance.js +51 -0
  132. package/dist/studio-app/.gitkeep +1 -0
  133. package/dist/studio-app/assets/feltdb_wasm-BXMn9UxO.js +1 -0
  134. package/dist/studio-app/assets/feltdb_wasm_bg-bYYbZeRM.wasm +0 -0
  135. package/dist/studio-app/assets/index-B-lZjdtI.js +28 -0
  136. package/dist/studio-app/assets/index-CB-Eed9V.css +1 -0
  137. package/dist/studio-app/index.html +3 -0
  138. package/dist/wasm/feltdb_wasm.d.ts +461 -0
  139. package/dist/wasm/feltdb_wasm.js +1690 -0
  140. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  141. package/dist/wasm/feltdb_wasm_bg.wasm.d.ts +84 -0
  142. package/dist/wasm/package.json +16 -0
  143. 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,7 @@
1
+ /**
2
+ * @feltdb/react - React Hooks for FeltDB
3
+ */
4
+ export * from './useFeltDB.js';
5
+ export * from './useCollection.js';
6
+ export * from './useCapability.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -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,6 @@
1
+ /**
2
+ * @feltdb/react - React Hooks for FeltDB
3
+ */
4
+ export * from './useFeltDB.js';
5
+ export * from './useCollection.js';
6
+ export * from './useCapability.js';
@@ -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"}