@feltdb/core 0.4.5 → 0.4.7

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 (38) hide show
  1. package/README.md +9 -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 +251 -0
  13. package/dist/create/create.js +1862 -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/react/useFeltDB.d.ts +1 -1
  20. package/dist/react/useFeltDB.js +1 -1
  21. package/dist/studio/KeyManagementPanel-B0s0xAXz.js +298 -0
  22. package/dist/studio/components/KeyManagementPanel.d.ts.map +1 -1
  23. package/dist/studio/components/KeyManagementPanel.js +1 -1
  24. package/dist/studio/components/index.js +2 -2
  25. package/dist/studio/{components-BRYUceo9.js → components-BAycgZhP.js} +1 -1
  26. package/dist/studio/index.js +2 -2
  27. package/dist/studio-app/assets/{feltdb_wasm-BXMn9UxO.js → feltdb_wasm-Bb1Pg6qz.js} +1 -1
  28. package/dist/studio-app/assets/feltdb_wasm_bg-2_wVudcZ.wasm +0 -0
  29. package/dist/studio-app/assets/{index-B-lZjdtI.js → index-DKVLtS37.js} +2 -2
  30. package/dist/studio-app/index.html +1 -1
  31. package/dist/wasm/feltdb_wasm.d.ts +461 -0
  32. package/dist/wasm/feltdb_wasm.js +1690 -0
  33. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  34. package/dist/wasm/feltdb_wasm_bg.wasm.d.ts +84 -0
  35. package/dist/wasm/package.json +16 -0
  36. package/package.json +11 -5
  37. package/dist/studio/KeyManagementPanel-BOvWTRyH.js +0 -246
  38. package/dist/studio-app/assets/feltdb_wasm_bg-bYYbZeRM.wasm +0 -0
package/README.md CHANGED
@@ -8,6 +8,15 @@ The main FeltDB API. This package provides a simple, state-first interface for w
8
8
  npm install @feltdb/core
9
9
  ```
10
10
 
11
+ This single package includes the database SDK, WASM runtime, React bindings,
12
+ migration tools, Studio application, `feltdb` CLI, and `create-feltdb`
13
+ scaffolder. The only separate FeltDB package is the optional `@feltdb/webllm`.
14
+
15
+ ```bash
16
+ npx --package @feltdb/core create-feltdb my-app
17
+ npx --package @feltdb/core feltdb studio
18
+ ```
19
+
11
20
  React bindings and migration tooling ship as subpath exports of this package:
12
21
 
13
22
  ```typescript
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ await import('../dist/create/cli.js');
package/bin/feltdb.js ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+
3
+ await import('../dist/cli/cli.js');
@@ -35,7 +35,7 @@ export class AnalyticsBackend {
35
35
  try {
36
36
  // Dynamic import of WASM module when available
37
37
  // @ts-ignore - WASM module may not exist during development
38
- const wasmModule = await import('@feltdb/wasm');
38
+ const wasmModule = await import('./wasm/feltdb_wasm.js');
39
39
  // Create WASM analytics instance
40
40
  const wasmAnalytics = new wasmModule.WasmAnalytics();
41
41
  // Replace backend with WASM implementation
@@ -0,0 +1,236 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import * as https from 'https';
4
+ import * as http from 'http';
5
+ export class FeltDBClient {
6
+ constructor() {
7
+ this.baseURL = process.env.FELTDB_URL || 'https://api.feltdb.com';
8
+ this.token = null;
9
+ this.config = null;
10
+ this.loadConfig();
11
+ }
12
+ loadConfig() {
13
+ const configPath = path.join(process.env.HOME || '', '.feltdb', 'config.json');
14
+ if (fs.existsSync(configPath)) {
15
+ try {
16
+ const data = fs.readFileSync(configPath, 'utf-8');
17
+ this.config = JSON.parse(data);
18
+ this.token = this.config.token || null;
19
+ }
20
+ catch (e) {
21
+ // Config not found or invalid
22
+ }
23
+ }
24
+ }
25
+ saveConfig(config) {
26
+ const configDir = path.join(process.env.HOME || '', '.feltdb');
27
+ if (!fs.existsSync(configDir)) {
28
+ fs.mkdirSync(configDir, { recursive: true });
29
+ }
30
+ fs.writeFileSync(path.join(configDir, 'config.json'), JSON.stringify(config, null, 2));
31
+ this.config = config;
32
+ this.token = config.token || null;
33
+ }
34
+ async request(options) {
35
+ return new Promise((resolve, reject) => {
36
+ const url = new URL(this.baseURL + options.path);
37
+ const headers = {
38
+ 'Content-Type': 'application/json',
39
+ };
40
+ if (options.token || this.token) {
41
+ headers['Authorization'] = `Bearer ${options.token || this.token}`;
42
+ }
43
+ const body = options.body ? JSON.stringify(options.body) : undefined;
44
+ const transport = url.protocol === 'http:' ? http : https;
45
+ const req = transport.request(url, {
46
+ method: options.method,
47
+ headers,
48
+ }, (res) => {
49
+ let data = '';
50
+ res.on('data', chunk => data += chunk);
51
+ res.on('end', () => {
52
+ if (res.statusCode === 401) {
53
+ reject(new Error('Unauthorized. Please run `feltdb login`'));
54
+ }
55
+ else if (res.statusCode && res.statusCode >= 400) {
56
+ try {
57
+ const errorData = JSON.parse(data);
58
+ reject(new Error(errorData.message || `HTTP ${res.statusCode}`));
59
+ }
60
+ catch {
61
+ reject(new Error(`HTTP ${res.statusCode}`));
62
+ }
63
+ }
64
+ else {
65
+ try {
66
+ resolve(JSON.parse(data));
67
+ }
68
+ catch {
69
+ resolve(data);
70
+ }
71
+ }
72
+ });
73
+ });
74
+ req.on('error', reject);
75
+ if (body)
76
+ req.write(body);
77
+ req.end();
78
+ });
79
+ }
80
+ async authenticate(email, password) {
81
+ const response = await this.request({
82
+ method: 'POST',
83
+ path: '/auth/login',
84
+ body: { email, password },
85
+ });
86
+ return response;
87
+ }
88
+ async getApplications() {
89
+ if (!this.config?.account) {
90
+ throw new Error('No account configured. Run `feltdb login` first.');
91
+ }
92
+ return this.request({
93
+ method: 'GET',
94
+ path: `/accounts/${this.config.account}/applications`,
95
+ });
96
+ }
97
+ async getApplication(appId) {
98
+ if (!this.config?.account) {
99
+ throw new Error('No account configured.');
100
+ }
101
+ return this.request({
102
+ method: 'GET',
103
+ path: `/accounts/${this.config.account}/applications/${appId}`,
104
+ });
105
+ }
106
+ async createApplication(data) {
107
+ if (!this.config?.account) {
108
+ throw new Error('No account configured.');
109
+ }
110
+ return this.request({
111
+ method: 'POST',
112
+ path: `/accounts/${this.config.account}/applications`,
113
+ body: data,
114
+ });
115
+ }
116
+ async updateApplication(appId, data) {
117
+ if (!this.config?.account) {
118
+ throw new Error('No account configured.');
119
+ }
120
+ return this.request({
121
+ method: 'PUT',
122
+ path: `/accounts/${this.config.account}/applications/${appId}`,
123
+ body: data,
124
+ });
125
+ }
126
+ async publishVersion(appId, data) {
127
+ if (!this.config?.account) {
128
+ throw new Error('No account configured.');
129
+ }
130
+ return this.request({
131
+ method: 'POST',
132
+ path: `/accounts/${this.config.account}/applications/${appId}/versions`,
133
+ body: data,
134
+ });
135
+ }
136
+ async createDeployment(appId, versionId, topology) {
137
+ if (!this.config?.account) {
138
+ throw new Error('No account configured.');
139
+ }
140
+ return this.request({
141
+ method: 'POST',
142
+ path: `/accounts/${this.config.account}/applications/${appId}/deployments`,
143
+ body: { version_id: versionId, topology },
144
+ });
145
+ }
146
+ async planDeployment(input) {
147
+ return this.request({ method: 'POST', path: '/v1/deployments/plan', body: input });
148
+ }
149
+ async certifyDeployment(plan) {
150
+ return this.request({ method: 'POST', path: '/v1/deployments/certify', body: { plan } });
151
+ }
152
+ async executeDeployment(plan) {
153
+ return this.request({ method: 'POST', path: '/v1/deployments', body: { plan } });
154
+ }
155
+ async verifyRelease(releaseId) {
156
+ return this.request({ method: 'POST', path: `/v1/releases/${encodeURIComponent(releaseId)}/verify` });
157
+ }
158
+ async publishRelease(releaseId) {
159
+ return this.request({ method: 'POST', path: `/v1/releases/${encodeURIComponent(releaseId)}/publish` });
160
+ }
161
+ async deploymentOperation(deploymentId, operation, body) {
162
+ return this.request({ method: 'POST', path: `/v1/deployments/${encodeURIComponent(deploymentId)}/${operation}`, body });
163
+ }
164
+ async getDeploymentAudit(deploymentId) {
165
+ return this.request({ method: 'GET', path: `/v1/deployments/${encodeURIComponent(deploymentId)}/audit` });
166
+ }
167
+ async certificationRequest(method, path, body) {
168
+ if (!path.startsWith('/'))
169
+ throw new Error('Certification path must begin with /');
170
+ return this.request({ method, path, body });
171
+ }
172
+ async getDeployments(appId) {
173
+ if (!this.config?.account) {
174
+ throw new Error('No account configured.');
175
+ }
176
+ return this.request({
177
+ method: 'GET',
178
+ path: `/accounts/${this.config.account}/applications/${appId}/deployments`,
179
+ });
180
+ }
181
+ async startExecution(appId, workloadId, input) {
182
+ if (!this.config?.account) {
183
+ throw new Error('No account configured.');
184
+ }
185
+ return this.request({
186
+ method: 'POST',
187
+ path: `/accounts/${this.config.account}/applications/${appId}/executions`,
188
+ body: { workload_id: workloadId, input },
189
+ });
190
+ }
191
+ async getExecutions(appId) {
192
+ if (!this.config?.account) {
193
+ throw new Error('No account configured.');
194
+ }
195
+ return this.request({
196
+ method: 'GET',
197
+ path: `/accounts/${this.config.account}/applications/${appId}/executions`,
198
+ });
199
+ }
200
+ async exportData(appId, format, scope) {
201
+ if (!this.config?.account) {
202
+ throw new Error('No account configured.');
203
+ }
204
+ return this.request({
205
+ method: 'POST',
206
+ path: `/accounts/${this.config.account}/applications/${appId}/export`,
207
+ body: { format, scope },
208
+ });
209
+ }
210
+ async createBackup(appId) {
211
+ if (!this.config?.account) {
212
+ throw new Error('No account configured.');
213
+ }
214
+ return this.request({
215
+ method: 'POST',
216
+ path: `/accounts/${this.config.account}/applications/${appId}/backup`,
217
+ });
218
+ }
219
+ async restoreBackup(appId, backupId) {
220
+ if (!this.config?.account) {
221
+ throw new Error('No account configured.');
222
+ }
223
+ return this.request({
224
+ method: 'POST',
225
+ path: `/accounts/${this.config.account}/applications/${appId}/restore`,
226
+ body: { backup_id: backupId },
227
+ });
228
+ }
229
+ }
230
+ let client = null;
231
+ export function getClient() {
232
+ if (!client) {
233
+ client = new FeltDBClient();
234
+ }
235
+ return client;
236
+ }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * feltdb CLI
4
+ *
5
+ * Developer tools for FeltDB applications
6
+ */
7
+ import { handleCommand } from './commands.js';
8
+ async function main() {
9
+ const command = process.argv[2] || 'help';
10
+ try {
11
+ await handleCommand(command, process.argv.slice(3));
12
+ }
13
+ catch (error) {
14
+ console.error('Error:', error);
15
+ process.exit(1);
16
+ }
17
+ }
18
+ main();