@feltdb/core 0.4.8 → 0.4.9
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/dist/cli/commands.js +41 -8
- package/dist/cli/index.js +1 -1
- package/dist/create/cli.js +99 -25
- package/dist/create/create.js +678 -850
- package/dist/create/index.js +1 -0
- package/dist/create/managed-account.js +61 -0
- package/dist/create/package-versions.js +1 -1
- package/dist/studio/{KeyManagementPanel-B0s0xAXz.js → KeyManagementPanel-DZuSeWBK.js} +80 -100
- package/dist/studio/app.d.ts +4 -1
- package/dist/studio/app.d.ts.map +1 -1
- package/dist/studio/components/KeyManagementPanel.d.ts +1 -0
- package/dist/studio/components/KeyManagementPanel.d.ts.map +1 -1
- package/dist/studio/components/KeyManagementPanel.js +1 -1
- package/dist/studio/components/SettingsPanel.d.ts +6 -2
- package/dist/studio/components/SettingsPanel.d.ts.map +1 -1
- package/dist/studio/components/index.js +2 -2
- package/dist/studio/{components-BAycgZhP.js → components-gmwCs-Pb.js} +44 -45
- package/dist/studio/index.js +57 -48
- package/dist/studio/studio.css +1 -1
- package/dist/studio-app/assets/{index-DKVLtS37.js → index-BCrZl0OT.js} +2 -2
- package/dist/studio-app/assets/{index-CB-Eed9V.css → index-BkHEyTzN.css} +1 -1
- package/dist/studio-app/index.html +2 -2
- package/package.json +1 -1
package/dist/cli/commands.js
CHANGED
|
@@ -7,7 +7,23 @@ import http from 'http';
|
|
|
7
7
|
import { createRequire } from 'module';
|
|
8
8
|
import { spawn, spawnSync } from 'child_process';
|
|
9
9
|
import { createFeltDB, diffFlowSpec, formatFlowSpec, parseFlowSpec, planFlowSpecMigration, validateFlowSpec } from '@feltdb/core';
|
|
10
|
-
const RELEASE_VERSION = '0.4.
|
|
10
|
+
const RELEASE_VERSION = '0.4.9';
|
|
11
|
+
function loadProjectEnvironment(file = path.resolve('.env.local')) {
|
|
12
|
+
if (!fs.existsSync(file))
|
|
13
|
+
return;
|
|
14
|
+
for (const rawLine of fs.readFileSync(file, 'utf8').split(/\r?\n/)) {
|
|
15
|
+
const line = rawLine.trim();
|
|
16
|
+
if (!line || line.startsWith('#'))
|
|
17
|
+
continue;
|
|
18
|
+
const separator = line.indexOf('=');
|
|
19
|
+
if (separator < 1)
|
|
20
|
+
continue;
|
|
21
|
+
const key = line.slice(0, separator).trim();
|
|
22
|
+
const value = line.slice(separator + 1).trim().replace(/^(['"])(.*)\1$/, '$2');
|
|
23
|
+
if (!(key in process.env))
|
|
24
|
+
process.env[key] = value;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
11
27
|
export async function handleCommand(command, args) {
|
|
12
28
|
switch (command) {
|
|
13
29
|
case 'studio':
|
|
@@ -351,7 +367,8 @@ function runLocalVite(args, waitForExit) {
|
|
|
351
367
|
});
|
|
352
368
|
}
|
|
353
369
|
async function handleDev(args) {
|
|
354
|
-
var _a;
|
|
370
|
+
var _a, _b, _c;
|
|
371
|
+
loadProjectEnvironment();
|
|
355
372
|
console.log('🚀 Starting FeltDB development server...\n');
|
|
356
373
|
// Check for feltdb.config.json
|
|
357
374
|
const configPath = path.join(process.cwd(), 'feltdb.config.json');
|
|
@@ -360,6 +377,18 @@ async function handleDev(args) {
|
|
|
360
377
|
process.exit(1);
|
|
361
378
|
}
|
|
362
379
|
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
380
|
+
if (config.runtime === 'managed') {
|
|
381
|
+
(_a = process.env).VITE_FELTDB_URL || (_a.VITE_FELTDB_URL = process.env.VITE_FELTDB_MANAGED_URL);
|
|
382
|
+
(_b = process.env).VITE_FELTDB_API_KEY || (_b.VITE_FELTDB_API_KEY = process.env.VITE_FELTDB_MANAGED_API_KEY);
|
|
383
|
+
}
|
|
384
|
+
if (config.runtime === 'managed' && (!process.env.VITE_FELTDB_URL || !process.env.VITE_FELTDB_API_KEY)) {
|
|
385
|
+
throw new Error('Managed runtime requires VITE_FELTDB_MANAGED_URL and VITE_FELTDB_MANAGED_API_KEY in .env.local. Re-run managed setup or add your managed connection.');
|
|
386
|
+
}
|
|
387
|
+
const runtimeNamespace = config.runtime === 'managed'
|
|
388
|
+
? process.env.VITE_FELTDB_MANAGED_NAMESPACE || config.namespace
|
|
389
|
+
: config.namespace;
|
|
390
|
+
const appPort = args.includes('--port') ? args[args.indexOf('--port') + 1] || '5173' : '5173';
|
|
391
|
+
const studioPort = args.includes('--studio-port') ? args[args.indexOf('--studio-port') + 1] || '3000' : '3000';
|
|
363
392
|
let selfHosted;
|
|
364
393
|
const stopSelfHosted = () => {
|
|
365
394
|
if (selfHosted && !selfHosted.killed)
|
|
@@ -380,20 +409,20 @@ async function handleDev(args) {
|
|
|
380
409
|
'-p', '7700:8080',
|
|
381
410
|
'-v', `${containerName}-data:/data`,
|
|
382
411
|
image,
|
|
412
|
+
'--allow-origin', `http://127.0.0.1:${appPort}`,
|
|
413
|
+
'--allow-origin', `http://127.0.0.1:${studioPort}`,
|
|
383
414
|
], { stdio: 'inherit' });
|
|
384
415
|
selfHosted.once('exit', code => {
|
|
385
416
|
if (code && code !== 0)
|
|
386
417
|
console.error(`Self-hosted FeltDB server exited with status ${code}`);
|
|
387
418
|
});
|
|
388
|
-
(
|
|
419
|
+
(_c = process.env).VITE_FELTDB_URL || (_c.VITE_FELTDB_URL = 'http://127.0.0.1:7700');
|
|
389
420
|
}
|
|
390
421
|
console.log('FeltDB Dev Server');
|
|
391
422
|
console.log(` Namespace: ${config.namespace}`);
|
|
392
423
|
console.log(` Runtime: ${config.runtime}`);
|
|
393
424
|
console.log(` Storage: ${config.storage}`);
|
|
394
425
|
console.log(` Distributed: ${config.distributed}\n`);
|
|
395
|
-
const appPort = args.includes('--port') ? args[args.indexOf('--port') + 1] || '5173' : '5173';
|
|
396
|
-
const studioPort = args.includes('--studio-port') ? args[args.indexOf('--studio-port') + 1] || '3000' : '3000';
|
|
397
426
|
const open = !args.includes('--no-open');
|
|
398
427
|
console.log(`Application: http://127.0.0.1:${appPort}`);
|
|
399
428
|
console.log(`Studio: http://127.0.0.1:${studioPort}\n`);
|
|
@@ -407,8 +436,9 @@ async function handleDev(args) {
|
|
|
407
436
|
process.once('SIGTERM', () => { stopAll(); process.exit(143); });
|
|
408
437
|
await handleStudio([
|
|
409
438
|
'--port', studioPort,
|
|
410
|
-
'--namespace',
|
|
411
|
-
|
|
439
|
+
'--namespace', runtimeNamespace || 'default',
|
|
440
|
+
'--runtime', config.runtime || 'browser',
|
|
441
|
+
...((config.runtime === 'self-hosted' || config.runtime === 'managed') && process.env.VITE_FELTDB_URL ? ['--connect', process.env.VITE_FELTDB_URL] : []),
|
|
412
442
|
...(open ? [] : ['--no-open']),
|
|
413
443
|
]);
|
|
414
444
|
}
|
|
@@ -663,6 +693,9 @@ async function handleStudio(args) {
|
|
|
663
693
|
const namespace = args.includes('--namespace')
|
|
664
694
|
? args[args.indexOf('--namespace') + 1] || 'default'
|
|
665
695
|
: 'default';
|
|
696
|
+
const runtime = args.includes('--runtime')
|
|
697
|
+
? args[args.indexOf('--runtime') + 1] || 'browser'
|
|
698
|
+
: connectUrl ? 'remote' : 'browser';
|
|
666
699
|
if (connectUrl) {
|
|
667
700
|
console.log(`Connecting to: ${connectUrl}`);
|
|
668
701
|
console.log(`Remote Studio: http://localhost:${port}\n`);
|
|
@@ -700,7 +733,7 @@ async function handleStudio(args) {
|
|
|
700
733
|
fs.createReadStream(file).pipe(response);
|
|
701
734
|
});
|
|
702
735
|
await new Promise((resolve, reject) => { server.once('error', reject); server.listen(Number(port), '127.0.0.1', resolve); });
|
|
703
|
-
const parameters = new URLSearchParams({ namespace });
|
|
736
|
+
const parameters = new URLSearchParams({ namespace, runtime });
|
|
704
737
|
if (connectUrl)
|
|
705
738
|
parameters.set('connect', connectUrl);
|
|
706
739
|
const query = `?${parameters.toString()}`;
|
package/dist/cli/index.js
CHANGED
|
@@ -23,7 +23,7 @@ import * as path from 'path';
|
|
|
23
23
|
import * as readline from 'readline';
|
|
24
24
|
import { getClient } from './api-client.js';
|
|
25
25
|
import { loadFeltDBConfig, createDefaultConfig, validateModel, } from './config.js';
|
|
26
|
-
const VERSION = '0.4.
|
|
26
|
+
const VERSION = '0.4.9';
|
|
27
27
|
function prompt(question) {
|
|
28
28
|
const rl = readline.createInterface({
|
|
29
29
|
input: process.stdin,
|
package/dist/create/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ import readline from 'readline';
|
|
|
10
10
|
import { spawn } from 'child_process';
|
|
11
11
|
import { createProject } from './create.js';
|
|
12
12
|
import { FELTDB_PACKAGE_VERSION } from './package-versions.js';
|
|
13
|
+
import { configureManagedAccount } from './managed-account.js';
|
|
13
14
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
14
15
|
function parseArgs(args) {
|
|
15
16
|
const options = {
|
|
@@ -21,6 +22,18 @@ function parseArgs(args) {
|
|
|
21
22
|
};
|
|
22
23
|
for (let i = 0; i < args.length; i++) {
|
|
23
24
|
switch (args[i]) {
|
|
25
|
+
case '--browser':
|
|
26
|
+
options.runtime = 'browser';
|
|
27
|
+
break;
|
|
28
|
+
case '--server':
|
|
29
|
+
options.runtime = 'node';
|
|
30
|
+
break;
|
|
31
|
+
case '--self-host':
|
|
32
|
+
options.runtime = 'self-hosted';
|
|
33
|
+
break;
|
|
34
|
+
case '--managed':
|
|
35
|
+
options.runtime = 'managed';
|
|
36
|
+
break;
|
|
24
37
|
case '--runtime':
|
|
25
38
|
options.runtime = args[++i];
|
|
26
39
|
break;
|
|
@@ -49,6 +62,38 @@ function run(command, args, cwd) {
|
|
|
49
62
|
: reject(new Error(`${command} exited with status ${code ?? 'unknown'}`)));
|
|
50
63
|
});
|
|
51
64
|
}
|
|
65
|
+
async function prompt(message) {
|
|
66
|
+
const interface_ = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
67
|
+
return new Promise(resolve => interface_.question(message, value => { interface_.close(); resolve(value.trim()); }));
|
|
68
|
+
}
|
|
69
|
+
async function promptSecret(message) {
|
|
70
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
71
|
+
return '';
|
|
72
|
+
const input = process.stdin;
|
|
73
|
+
const output = process.stdout;
|
|
74
|
+
const wasRaw = input.isRaw;
|
|
75
|
+
readline.emitKeypressEvents(input);
|
|
76
|
+
input.setRawMode(true);
|
|
77
|
+
input.resume();
|
|
78
|
+
output.write(message);
|
|
79
|
+
return new Promise(resolve => {
|
|
80
|
+
let value = '';
|
|
81
|
+
const finish = () => { input.off('keypress', onKeypress); input.setRawMode(Boolean(wasRaw)); input.pause(); output.write('\n'); resolve(value); };
|
|
82
|
+
const onKeypress = (character, key) => {
|
|
83
|
+
if (key.ctrl && key.name === 'c')
|
|
84
|
+
process.exit(130);
|
|
85
|
+
if (key.name === 'return' || key.name === 'enter')
|
|
86
|
+
return finish();
|
|
87
|
+
if (key.name === 'backspace') {
|
|
88
|
+
value = value.slice(0, -1);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
if (!key.ctrl && !key.meta && character)
|
|
92
|
+
value += character;
|
|
93
|
+
};
|
|
94
|
+
input.on('keypress', onKeypress);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
52
97
|
async function select(message, choices, initialValue) {
|
|
53
98
|
let selected = Math.max(0, choices.findIndex(choice => choice.value === initialValue));
|
|
54
99
|
const input = process.stdin;
|
|
@@ -108,6 +153,7 @@ async function promptForOptions(defaults) {
|
|
|
108
153
|
{ label: 'Browser', value: 'browser', description: 'local-first with durable browser storage' },
|
|
109
154
|
{ label: 'Node.js', value: 'node', description: 'application server or worker' },
|
|
110
155
|
{ label: 'Self-hosted', value: 'self-hosted', description: 'dedicated FeltDB server' },
|
|
156
|
+
{ label: 'Managed', value: 'managed', description: 'FeltDB-hosted persistence, sync, and workloads' },
|
|
111
157
|
], defaults.runtime),
|
|
112
158
|
framework: await select('Choose an application framework:', [
|
|
113
159
|
{ label: 'React', value: 'react' },
|
|
@@ -134,22 +180,35 @@ Usage:
|
|
|
134
180
|
|
|
135
181
|
Examples:
|
|
136
182
|
create-feltdb my-app
|
|
137
|
-
create-feltdb my-app --
|
|
138
|
-
create-feltdb my-app --
|
|
183
|
+
create-feltdb my-app --browser
|
|
184
|
+
create-feltdb my-app --server
|
|
185
|
+
create-feltdb my-app --self-host
|
|
186
|
+
create-feltdb my-app --managed
|
|
187
|
+
create-feltdb my-app --framework react --yes
|
|
139
188
|
|
|
140
|
-
|
|
141
|
-
--
|
|
189
|
+
Deployment Target (Explicit):
|
|
190
|
+
--browser Local-first with durable browser storage (IndexedDB)
|
|
142
191
|
Best for: Client-side apps, offline-first experiences
|
|
192
|
+
No server required, full offline capability
|
|
143
193
|
|
|
144
|
-
--
|
|
194
|
+
--server Node.js server runtime with server-side FeltDB authority
|
|
145
195
|
Best for: Server-side applications, API servers
|
|
196
|
+
Requires production FeltDB instance or self-host
|
|
146
197
|
|
|
147
|
-
--
|
|
198
|
+
--self-host Dedicated FeltDB server with Docker Compose
|
|
148
199
|
Best for: Production deployments, multi-user systems
|
|
149
|
-
|
|
200
|
+
Generates Docker Compose with persistent /data volume
|
|
201
|
+
|
|
202
|
+
--managed Managed FeltDB runtime
|
|
203
|
+
Best for: Production without operating servers
|
|
204
|
+
Requires VITE_FELTDB_URL and VITE_FELTDB_API_KEY
|
|
150
205
|
|
|
151
206
|
Options:
|
|
152
|
-
--
|
|
207
|
+
--browser Explicit: Browser runtime with IndexedDB
|
|
208
|
+
--server Explicit: Node.js server runtime
|
|
209
|
+
--self-host Explicit: Self-hosted with Docker Compose
|
|
210
|
+
--managed Explicit: Managed FeltDB service
|
|
211
|
+
--runtime <runtime> Alternative: Set runtime (browser, node, self-hosted, managed)
|
|
153
212
|
--framework <framework> Choose framework: react or vanilla (default: react)
|
|
154
213
|
--no-distributed Disable distributed operation
|
|
155
214
|
--no-agents Exclude agent examples
|
|
@@ -160,11 +219,6 @@ Options:
|
|
|
160
219
|
-h, --help Show this help message
|
|
161
220
|
--version Show version number
|
|
162
221
|
|
|
163
|
-
Vector Search:
|
|
164
|
-
Vector search requires additional dependencies and setup. If you choose
|
|
165
|
-
"Search + vector search" during setup, make sure to review the documentation
|
|
166
|
-
for configuring your vector database connection.
|
|
167
|
-
|
|
168
222
|
Environment Variables:
|
|
169
223
|
FELTDB_IMAGE Override the default self-hosted container image
|
|
170
224
|
NODE_ENV Set to 'development' or 'production'
|
|
@@ -193,21 +247,31 @@ Learn more: https://github.com/rkendel1/feltdb`);
|
|
|
193
247
|
const shouldInstall = !args.includes('--no-install');
|
|
194
248
|
const shouldStart = !args.includes('--no-start');
|
|
195
249
|
let options = parseArgs(args);
|
|
250
|
+
const runtimeDescriptions = {
|
|
251
|
+
'browser': 'Browser with IndexedDB (local-first, no server)',
|
|
252
|
+
'node': 'Node.js server (server-side authority)',
|
|
253
|
+
'self-hosted': 'Self-hosted with Docker Compose (production)',
|
|
254
|
+
'managed': 'Managed FeltDB service (hosted persistence, sync, and workloads)',
|
|
255
|
+
};
|
|
256
|
+
if (!runtimeDescriptions[options.runtime]) {
|
|
257
|
+
throw new Error(`Unsupported runtime "${options.runtime}". Choose browser, node, self-hosted, or managed.`);
|
|
258
|
+
}
|
|
196
259
|
console.log('\n✨ Creating FeltDB Application\n');
|
|
197
260
|
if (!shouldAutoYes) {
|
|
198
261
|
options = await promptForOptions(options);
|
|
199
|
-
const runtimeDescriptions = {
|
|
200
|
-
'browser': 'Local-first with browser storage',
|
|
201
|
-
'node': 'Node.js server runtime',
|
|
202
|
-
'self-hosted': 'Dedicated FeltDB server',
|
|
203
|
-
};
|
|
204
|
-
console.log('\nConfiguration:');
|
|
205
|
-
console.log(` Runtime: ${options.runtime} (${runtimeDescriptions[options.runtime]})`);
|
|
206
|
-
console.log(` Framework: ${options.framework}`);
|
|
207
|
-
console.log(` Distributed: ${options.distributed ? 'yes' : 'no'}`);
|
|
208
|
-
console.log(` Agents: ${options.agents ? 'yes' : 'no'}`);
|
|
209
|
-
console.log(` Capabilities: ${options.capabilities}\n`);
|
|
210
262
|
}
|
|
263
|
+
// Display the deployment target explicitly
|
|
264
|
+
console.log('\n═══════════════════════════════════════════════');
|
|
265
|
+
console.log('📦 DEPLOYMENT TARGET');
|
|
266
|
+
console.log('═══════════════════════════════════════════════');
|
|
267
|
+
console.log(`\nRuntime: ${options.runtime.toUpperCase()}`);
|
|
268
|
+
console.log(`Description: ${runtimeDescriptions[options.runtime]}`);
|
|
269
|
+
console.log(`Framework: ${options.framework}`);
|
|
270
|
+
console.log(`Distributed: ${options.distributed ? 'yes' : 'no'}`);
|
|
271
|
+
console.log(`Agents: ${options.agents ? 'yes' : 'no'}`);
|
|
272
|
+
console.log(`Capabilities: ${options.capabilities}`);
|
|
273
|
+
console.log('\n═══════════════════════════════════════════════\n');
|
|
274
|
+
const projectDir = path.resolve(process.cwd(), projectName);
|
|
211
275
|
try {
|
|
212
276
|
await createProject({
|
|
213
277
|
projectName,
|
|
@@ -219,8 +283,18 @@ Learn more: https://github.com/rkendel1/feltdb`);
|
|
|
219
283
|
agents: options.agents,
|
|
220
284
|
capabilities: options.capabilities,
|
|
221
285
|
});
|
|
286
|
+
if (options.runtime === 'managed') {
|
|
287
|
+
console.log('\n☁️ Setting up your managed FeltDB account...\n');
|
|
288
|
+
const email = process.env.FELTDB_MANAGED_EMAIL || (shouldAutoYes ? '' : await prompt('Email: '));
|
|
289
|
+
const password = process.env.FELTDB_MANAGED_PASSWORD || (shouldAutoYes ? '' : await promptSecret('Password (8+ characters): '));
|
|
290
|
+
if (!email || password.length < 8) {
|
|
291
|
+
throw new Error('Managed setup needs an email and an 8+ character password. In non-interactive mode set FELTDB_MANAGED_EMAIL and FELTDB_MANAGED_PASSWORD.');
|
|
292
|
+
}
|
|
293
|
+
const managed = await configureManagedAccount({ projectDir, applicationName: projectName, namespace: projectName, email, password });
|
|
294
|
+
console.log(`✓ Managed application: ${managed.application.name}`);
|
|
295
|
+
console.log(`✓ Managed environment written to ${projectName}/.env.local`);
|
|
296
|
+
}
|
|
222
297
|
console.log('\n✅ FeltDB application created successfully!\n');
|
|
223
|
-
const projectDir = path.resolve(process.cwd(), projectName);
|
|
224
298
|
const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
|
|
225
299
|
if (shouldInstall) {
|
|
226
300
|
console.log('📦 Installing application, Studio, and local AI dependencies...\n');
|