@feltdb/core 0.4.5 → 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 +9 -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/react/useFeltDB.d.ts +1 -1
- package/dist/react/useFeltDB.js +1 -1
- 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 +11 -5
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Docker Compose generator for self-hosted FeltDB deployments
|
|
3
|
+
*
|
|
4
|
+
* Generates:
|
|
5
|
+
* - docker-compose.yml with three services (FeltDB, App, Studio)
|
|
6
|
+
* - Dockerfile for application container
|
|
7
|
+
* - .dockerignore for optimized builds
|
|
8
|
+
* - Environment configuration
|
|
9
|
+
*/
|
|
10
|
+
export function generateDockerCompose(config) {
|
|
11
|
+
return `version: '3.9'
|
|
12
|
+
|
|
13
|
+
services:
|
|
14
|
+
feltdb:
|
|
15
|
+
image: rkendel1/feltdb:latest
|
|
16
|
+
container_name: \${COMPOSE_PROJECT_NAME}-feltdb
|
|
17
|
+
environment:
|
|
18
|
+
FELTDB_APP_NAME: \${FELTDB_APP_NAME:-${config.appName}}
|
|
19
|
+
FELTDB_APP_ID: \${FELTDB_APP_ID:-${config.appId}}
|
|
20
|
+
FELTDB_VERSION: \${FELTDB_VERSION:-${config.version}}
|
|
21
|
+
FELTDB_PEERS: \${FELTDB_PEERS:-}
|
|
22
|
+
FELTDB_REPLICATION_PORT: ${config.replicationPort}
|
|
23
|
+
NODE_ENV: \${NODE_ENV:-production}
|
|
24
|
+
ports:
|
|
25
|
+
- "\${FELTDB_API_PORT:-${config.port}}:7700"
|
|
26
|
+
- "\${FELTDB_REPLICATION_PORT:-${config.replicationPort}}:${config.replicationPort}"
|
|
27
|
+
volumes:
|
|
28
|
+
- feltdb_data:/data
|
|
29
|
+
- ./feltdb.flow:/app/feltdb.flow:ro
|
|
30
|
+
healthcheck:
|
|
31
|
+
test: ["CMD", "curl", "-f", "http://localhost:7700/health"]
|
|
32
|
+
interval: 10s
|
|
33
|
+
timeout: 5s
|
|
34
|
+
retries: 3
|
|
35
|
+
start_period: 30s
|
|
36
|
+
restart: unless-stopped
|
|
37
|
+
networks:
|
|
38
|
+
- feltdb_network
|
|
39
|
+
labels:
|
|
40
|
+
app.feltdb/component: "database"
|
|
41
|
+
app.feltdb/version: "${config.version}"
|
|
42
|
+
|
|
43
|
+
app:
|
|
44
|
+
build:
|
|
45
|
+
context: .
|
|
46
|
+
dockerfile: Dockerfile
|
|
47
|
+
args:
|
|
48
|
+
NODE_ENV: production
|
|
49
|
+
container_name: \${COMPOSE_PROJECT_NAME}-app
|
|
50
|
+
environment:
|
|
51
|
+
FELTDB_API_URL: http://feltdb:7700
|
|
52
|
+
FELTDB_APP_NAME: \${FELTDB_APP_NAME:-${config.appName}}
|
|
53
|
+
NODE_ENV: \${NODE_ENV:-production}
|
|
54
|
+
ports:
|
|
55
|
+
- "\${APP_PORT:-3000}:3000"
|
|
56
|
+
depends_on:
|
|
57
|
+
feltdb:
|
|
58
|
+
condition: service_healthy
|
|
59
|
+
volumes:
|
|
60
|
+
- ./src:/app/src
|
|
61
|
+
- app_node_modules:/app/node_modules
|
|
62
|
+
healthcheck:
|
|
63
|
+
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
|
64
|
+
interval: 10s
|
|
65
|
+
timeout: 5s
|
|
66
|
+
retries: 3
|
|
67
|
+
start_period: 30s
|
|
68
|
+
restart: unless-stopped
|
|
69
|
+
networks:
|
|
70
|
+
- feltdb_network
|
|
71
|
+
labels:
|
|
72
|
+
app.feltdb/component: "application"
|
|
73
|
+
app.feltdb/version: "${config.version}"
|
|
74
|
+
|
|
75
|
+
studio:
|
|
76
|
+
image: rkendel1/feltdb-studio:latest
|
|
77
|
+
container_name: \${COMPOSE_PROJECT_NAME}-studio
|
|
78
|
+
environment:
|
|
79
|
+
FELTDB_API_URL: http://feltdb:7700
|
|
80
|
+
APP_URL: http://app:3000
|
|
81
|
+
ports:
|
|
82
|
+
- "\${STUDIO_PORT:-${config.studioPort}}:8000"
|
|
83
|
+
depends_on:
|
|
84
|
+
- feltdb
|
|
85
|
+
- app
|
|
86
|
+
networks:
|
|
87
|
+
- feltdb_network
|
|
88
|
+
labels:
|
|
89
|
+
app.feltdb/component: "studio"
|
|
90
|
+
|
|
91
|
+
networks:
|
|
92
|
+
feltdb_network:
|
|
93
|
+
driver: bridge
|
|
94
|
+
labels:
|
|
95
|
+
app.feltdb/network: "internal"
|
|
96
|
+
|
|
97
|
+
volumes:
|
|
98
|
+
feltdb_data:
|
|
99
|
+
driver: local
|
|
100
|
+
labels:
|
|
101
|
+
app.feltdb/data: "durable-operations-log"
|
|
102
|
+
app_node_modules:
|
|
103
|
+
driver: local
|
|
104
|
+
`;
|
|
105
|
+
}
|
|
106
|
+
export function generateDockerfile(config, framework) {
|
|
107
|
+
const buildCommand = framework === 'react' ? 'npm run build' : 'npm run build';
|
|
108
|
+
return `# FeltDB Application Container
|
|
109
|
+
# Multi-stage build for optimized production image
|
|
110
|
+
|
|
111
|
+
FROM node:18-alpine AS builder
|
|
112
|
+
|
|
113
|
+
WORKDIR /app
|
|
114
|
+
|
|
115
|
+
# Install dependencies
|
|
116
|
+
COPY package.json package-lock.json ./
|
|
117
|
+
RUN npm ci --only=production && npm cache clean --force
|
|
118
|
+
|
|
119
|
+
# Copy source
|
|
120
|
+
COPY . .
|
|
121
|
+
|
|
122
|
+
# Build application
|
|
123
|
+
RUN ${buildCommand}
|
|
124
|
+
|
|
125
|
+
# Final stage
|
|
126
|
+
FROM node:18-alpine
|
|
127
|
+
|
|
128
|
+
WORKDIR /app
|
|
129
|
+
|
|
130
|
+
# Install health check utility
|
|
131
|
+
RUN apk add --no-cache curl
|
|
132
|
+
|
|
133
|
+
# Copy built application
|
|
134
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
135
|
+
COPY --from=builder /app/dist ./dist
|
|
136
|
+
COPY --from=builder /app/package.json ./package.json
|
|
137
|
+
COPY --from=builder /app/feltdb.flow ./feltdb.flow
|
|
138
|
+
|
|
139
|
+
# Create data directory for Node runtime
|
|
140
|
+
RUN mkdir -p /data && chmod 755 /data
|
|
141
|
+
|
|
142
|
+
# Non-root user for security
|
|
143
|
+
RUN addgroup -g 1001 -S nodejs
|
|
144
|
+
RUN adduser -S nodejs -u 1001
|
|
145
|
+
USER nodejs
|
|
146
|
+
|
|
147
|
+
# Health check
|
|
148
|
+
HEALTHCHECK --interval=10s --timeout=5s --retries=3 --start-period=30s \\
|
|
149
|
+
CMD curl -f http://localhost:3000/health || exit 1
|
|
150
|
+
|
|
151
|
+
# Startup
|
|
152
|
+
ENV NODE_ENV=production
|
|
153
|
+
EXPOSE 3000
|
|
154
|
+
|
|
155
|
+
CMD ["node", "dist/index.js"]
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
export function generateDockerIgnore() {
|
|
159
|
+
return `node_modules
|
|
160
|
+
npm-debug.log
|
|
161
|
+
dist
|
|
162
|
+
build
|
|
163
|
+
.git
|
|
164
|
+
.gitignore
|
|
165
|
+
.env
|
|
166
|
+
.env.local
|
|
167
|
+
.env.*.local
|
|
168
|
+
.DS_Store
|
|
169
|
+
*.log
|
|
170
|
+
.feltdb/keys.json
|
|
171
|
+
.feltdb/connection.json
|
|
172
|
+
.nextc
|
|
173
|
+
.next
|
|
174
|
+
coverage
|
|
175
|
+
.nyc_output
|
|
176
|
+
.cache
|
|
177
|
+
.turbo
|
|
178
|
+
`;
|
|
179
|
+
}
|
|
180
|
+
export function generateDotEnvLocal(config) {
|
|
181
|
+
return `# Docker Compose Environment
|
|
182
|
+
# Generated by create-feltdb for \${config.appName}
|
|
183
|
+
|
|
184
|
+
COMPOSE_PROJECT_NAME=${config.appName.toLowerCase().replace(/[^a-z0-9]/g, '-')}
|
|
185
|
+
|
|
186
|
+
# FeltDB Configuration
|
|
187
|
+
FELTDB_APP_NAME=${config.appName}
|
|
188
|
+
FELTDB_APP_ID=${config.appId}
|
|
189
|
+
FELTDB_VERSION=${config.version}
|
|
190
|
+
FELTDB_API_PORT=${config.port}
|
|
191
|
+
FELTDB_REPLICATION_PORT=${config.replicationPort}
|
|
192
|
+
FELTDB_PEERS=
|
|
193
|
+
|
|
194
|
+
# Application Configuration
|
|
195
|
+
APP_PORT=3000
|
|
196
|
+
FELTDB_API_URL=http://feltdb:7700
|
|
197
|
+
|
|
198
|
+
# Studio Configuration
|
|
199
|
+
STUDIO_PORT=${config.studioPort}
|
|
200
|
+
|
|
201
|
+
# Runtime
|
|
202
|
+
NODE_ENV=production
|
|
203
|
+
`;
|
|
204
|
+
}
|
|
205
|
+
export function generateHealthCheckScript() {
|
|
206
|
+
return `#!/bin/bash
|
|
207
|
+
|
|
208
|
+
# Multi-service health check orchestration
|
|
209
|
+
# Ensures all services are ready before marking deployment as healthy
|
|
210
|
+
|
|
211
|
+
set -e
|
|
212
|
+
|
|
213
|
+
TIMEOUT=60
|
|
214
|
+
ELAPSED=0
|
|
215
|
+
INTERVAL=2
|
|
216
|
+
|
|
217
|
+
echo "[Health Check] Starting orchestration check (timeout: \${TIMEOUT}s)"
|
|
218
|
+
|
|
219
|
+
# Wait for FeltDB
|
|
220
|
+
echo "[Health Check] Checking FeltDB service..."
|
|
221
|
+
while [ \$ELAPSED -lt \$TIMEOUT ]; do
|
|
222
|
+
if curl -s -f http://feltdb:7700/health > /dev/null 2>&1; then
|
|
223
|
+
STATE=\$(curl -s http://feltdb:7700/health | grep -o '"state":"[^"]*' | cut -d'"' -f4)
|
|
224
|
+
if [ "\$STATE" = "ready" ] || [ "\$STATE" = "recovering" ]; then
|
|
225
|
+
echo "[Health Check] FeltDB is \$STATE"
|
|
226
|
+
break
|
|
227
|
+
fi
|
|
228
|
+
fi
|
|
229
|
+
sleep \$INTERVAL
|
|
230
|
+
ELAPSED=\$((ELAPSED + INTERVAL))
|
|
231
|
+
done
|
|
232
|
+
|
|
233
|
+
if [ \$ELAPSED -ge \$TIMEOUT ]; then
|
|
234
|
+
echo "[Health Check] FAILED: FeltDB did not respond within timeout"
|
|
235
|
+
exit 1
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# Wait for application
|
|
239
|
+
echo "[Health Check] Checking application service..."
|
|
240
|
+
ELAPSED=0
|
|
241
|
+
while [ \$ELAPSED -lt \$TIMEOUT ]; do
|
|
242
|
+
if curl -s -f http://app:3000/health > /dev/null 2>&1; then
|
|
243
|
+
echo "[Health Check] Application is ready"
|
|
244
|
+
break
|
|
245
|
+
fi
|
|
246
|
+
sleep \$INTERVAL
|
|
247
|
+
ELAPSED=\$((ELAPSED + INTERVAL))
|
|
248
|
+
done
|
|
249
|
+
|
|
250
|
+
if [ \$ELAPSED -ge \$TIMEOUT ]; then
|
|
251
|
+
echo "[Health Check] FAILED: Application did not respond within timeout"
|
|
252
|
+
exit 1
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
echo "[Health Check] All services healthy - deployment ready"
|
|
256
|
+
exit 0
|
|
257
|
+
`;
|
|
258
|
+
}
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime-specific templates and configuration
|
|
3
|
+
*
|
|
4
|
+
* Generates runtime-appropriate file structure and configuration
|
|
5
|
+
* for Browser, Node, and Self-hosted deployment modes.
|
|
6
|
+
*/
|
|
7
|
+
export function generateBrowserRuntime(config) {
|
|
8
|
+
return {
|
|
9
|
+
feltdbInit: `import { createFeltDB } from '@feltdb/core';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Browser Runtime
|
|
13
|
+
*
|
|
14
|
+
* Local-first FeltDB with durable IndexedDB storage.
|
|
15
|
+
* No server required. Full offline capability.
|
|
16
|
+
*
|
|
17
|
+
* AppID: ${config.appId}
|
|
18
|
+
*/
|
|
19
|
+
export const db = createFeltDB({
|
|
20
|
+
namespace: '${config.appName}',
|
|
21
|
+
runtime: 'browser',
|
|
22
|
+
storage: {
|
|
23
|
+
type: 'indexeddb',
|
|
24
|
+
durable: true,
|
|
25
|
+
},
|
|
26
|
+
${config.distributed ? `
|
|
27
|
+
replication: {
|
|
28
|
+
enabled: false, // Browser cannot initiate replication
|
|
29
|
+
},` : ''}
|
|
30
|
+
health: {
|
|
31
|
+
onStateChange: (state: 'starting' | 'recovering' | 'ready' | 'failed') => {
|
|
32
|
+
console.log(\`[FeltDB Health] Browser state changed: \${state}\`);
|
|
33
|
+
window.dispatchEvent(new CustomEvent('feltdb:health', { detail: { state } }));
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Collections
|
|
39
|
+
export const documents = db.collection('documents');
|
|
40
|
+
export const reports = db.collection('reports');
|
|
41
|
+
`,
|
|
42
|
+
envExample: `# Browser Runtime
|
|
43
|
+
# No environment configuration needed.
|
|
44
|
+
# Data persists locally in IndexedDB.
|
|
45
|
+
NODE_ENV=development
|
|
46
|
+
`,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export function generateNodeRuntime(config) {
|
|
50
|
+
return {
|
|
51
|
+
feltdbInit: `import { createFeltDB } from '@feltdb/core';
|
|
52
|
+
import path from 'path';
|
|
53
|
+
import { fileURLToPath } from 'url';
|
|
54
|
+
import fs from 'fs';
|
|
55
|
+
|
|
56
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Node Runtime
|
|
60
|
+
*
|
|
61
|
+
* Server-side FeltDB with durable file-based storage.
|
|
62
|
+
* Can participate in distributed replication.
|
|
63
|
+
* Persistent operation log to /data directory.
|
|
64
|
+
*
|
|
65
|
+
* AppID: ${config.appId}
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
const dataDir = process.env.FELTDB_DATA_DIR || path.join(__dirname, '..', 'data');
|
|
69
|
+
if (!fs.existsSync(dataDir)) {
|
|
70
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const db = createFeltDB({
|
|
74
|
+
namespace: '${config.appName}',
|
|
75
|
+
runtime: 'node',
|
|
76
|
+
storage: {
|
|
77
|
+
type: 'file',
|
|
78
|
+
path: dataDir,
|
|
79
|
+
durable: true,
|
|
80
|
+
fsync: true,
|
|
81
|
+
},
|
|
82
|
+
${config.distributed ? `
|
|
83
|
+
replication: {
|
|
84
|
+
enabled: true,
|
|
85
|
+
port: parseInt(process.env.FELTDB_REPLICATION_PORT || '9000'),
|
|
86
|
+
},` : ''}
|
|
87
|
+
health: {
|
|
88
|
+
onStateChange: (state: 'starting' | 'recovering' | 'ready' | 'failed') => {
|
|
89
|
+
console.log(\`[FeltDB Health] Node state changed: \${state}\`);
|
|
90
|
+
// Emit to monitoring system
|
|
91
|
+
process.emit('feltdb:health', { state, timestamp: Date.now() });
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Collections
|
|
97
|
+
export const documents = db.collection('documents');
|
|
98
|
+
export const reports = db.collection('reports');
|
|
99
|
+
|
|
100
|
+
// Startup hook
|
|
101
|
+
export async function startup() {
|
|
102
|
+
console.log(\`[FeltDB] Starting Node runtime\`);
|
|
103
|
+
console.log(\`[FeltDB] App: ${config.appName} (${config.appId})\`);
|
|
104
|
+
console.log(\`[FeltDB] Version: ${config.version}\`);
|
|
105
|
+
console.log(\`[FeltDB] Data directory: \${dataDir}\`);
|
|
106
|
+
${config.distributed ? `console.log(\`[FeltDB] Replication enabled on port \${process.env.FELTDB_REPLICATION_PORT || 9000}\`);` : ''}
|
|
107
|
+
await db.ready();
|
|
108
|
+
console.log(\`[FeltDB] Ready\`);
|
|
109
|
+
}
|
|
110
|
+
`,
|
|
111
|
+
envExample: `# Node Runtime
|
|
112
|
+
FELTDB_DATA_DIR=./data
|
|
113
|
+
FELTDB_REPLICATION_PORT=9000
|
|
114
|
+
NODE_ENV=development
|
|
115
|
+
`,
|
|
116
|
+
startupScript: `#!/usr/bin/env node
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Node runtime startup orchestration
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
import { db, startup } from './feltdb.js';
|
|
123
|
+
|
|
124
|
+
async function main() {
|
|
125
|
+
try {
|
|
126
|
+
await startup();
|
|
127
|
+
|
|
128
|
+
// Start HTTP server for API
|
|
129
|
+
const { createServer } = await import('./server.js');
|
|
130
|
+
const server = createServer(db);
|
|
131
|
+
const port = process.env.FELTDB_API_PORT || 7700;
|
|
132
|
+
server.listen(port, () => {
|
|
133
|
+
console.log(\`[HTTP] API server listening on port \${port}\`);
|
|
134
|
+
});
|
|
135
|
+
} catch (err) {
|
|
136
|
+
console.error('[FeltDB] Startup failed:', err);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
main();
|
|
142
|
+
`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
export function generateSelfHostedRuntime(config) {
|
|
146
|
+
return {
|
|
147
|
+
feltdbInit: `import { createFeltDB } from '@feltdb/core';
|
|
148
|
+
import path from 'path';
|
|
149
|
+
import { fileURLToPath } from 'url';
|
|
150
|
+
import fs from 'fs';
|
|
151
|
+
|
|
152
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Self-hosted Runtime
|
|
156
|
+
*
|
|
157
|
+
* Containerized FeltDB with Docker Compose orchestration.
|
|
158
|
+
* Durable file-based storage with persistent volumes.
|
|
159
|
+
* Full replication topology with multi-node support.
|
|
160
|
+
*
|
|
161
|
+
* AppID: ${config.appId}
|
|
162
|
+
* Version: ${config.version}
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
const dataDir = process.env.FELTDB_DATA_DIR || '/data';
|
|
166
|
+
if (!fs.existsSync(dataDir)) {
|
|
167
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
export const db = createFeltDB({
|
|
171
|
+
namespace: '${config.appName}',
|
|
172
|
+
runtime: 'self-hosted',
|
|
173
|
+
storage: {
|
|
174
|
+
type: 'file',
|
|
175
|
+
path: dataDir,
|
|
176
|
+
durable: true,
|
|
177
|
+
fsync: true,
|
|
178
|
+
},
|
|
179
|
+
replication: {
|
|
180
|
+
enabled: true,
|
|
181
|
+
port: 9000,
|
|
182
|
+
peers: (process.env.FELTDB_PEERS || '').split(',').filter(Boolean),
|
|
183
|
+
},
|
|
184
|
+
health: {
|
|
185
|
+
onStateChange: (state: 'starting' | 'recovering' | 'ready' | 'failed') => {
|
|
186
|
+
console.log(\`[\${new Date().toISOString()}] [FeltDB] \${state.toUpperCase()}\`);
|
|
187
|
+
// Structured logging for container orchestration
|
|
188
|
+
process.emit('feltdb:health', { state, timestamp: Date.now() });
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Collections
|
|
194
|
+
export const documents = db.collection('documents');
|
|
195
|
+
export const reports = db.collection('reports');
|
|
196
|
+
|
|
197
|
+
// Startup with health check loop
|
|
198
|
+
export async function startup() {
|
|
199
|
+
console.log(\`[\${new Date().toISOString()}] [FeltDB] Container starting\`);
|
|
200
|
+
console.log(\`[FeltDB] App: ${config.appName} (${config.appId})\`);
|
|
201
|
+
console.log(\`[FeltDB] Version: ${config.version}\`);
|
|
202
|
+
console.log(\`[FeltDB] Runtime: self-hosted\`);
|
|
203
|
+
console.log(\`[FeltDB] Data directory: \${dataDir}\`);
|
|
204
|
+
|
|
205
|
+
await db.ready();
|
|
206
|
+
console.log(\`[\${new Date().toISOString()}] [FeltDB] READY\`);
|
|
207
|
+
}
|
|
208
|
+
`,
|
|
209
|
+
envExample: `# Self-hosted Docker Runtime
|
|
210
|
+
FELTDB_DATA_DIR=/data
|
|
211
|
+
FELTDB_APP_NAME=${config.appName}
|
|
212
|
+
FELTDB_APP_ID=${config.appId}
|
|
213
|
+
FELTDB_VERSION=${config.version}
|
|
214
|
+
FELTDB_REPLICATION_PORT=9000
|
|
215
|
+
FELTDB_PEERS=
|
|
216
|
+
NODE_ENV=production
|
|
217
|
+
`,
|
|
218
|
+
healthCheck: `#!/bin/sh
|
|
219
|
+
|
|
220
|
+
# Health check for Docker container
|
|
221
|
+
# Verifies FeltDB is responding and not in RECOVERING state
|
|
222
|
+
|
|
223
|
+
HEALTH_URL="http://localhost:7700/health"
|
|
224
|
+
TIMEOUT=5
|
|
225
|
+
|
|
226
|
+
# Query health endpoint
|
|
227
|
+
RESPONSE=\$(curl -s -m \${TIMEOUT} \${HEALTH_URL} 2>/dev/null)
|
|
228
|
+
|
|
229
|
+
if [ -z "\$RESPONSE" ]; then
|
|
230
|
+
echo "UNHEALTHY: No response from health endpoint"
|
|
231
|
+
exit 1
|
|
232
|
+
fi
|
|
233
|
+
|
|
234
|
+
STATE=\$(echo \$RESPONSE | grep -o '"state":"[^"]*' | cut -d'"' -f4)
|
|
235
|
+
|
|
236
|
+
case "\$STATE" in
|
|
237
|
+
ready)
|
|
238
|
+
echo "HEALTHY: State is ready"
|
|
239
|
+
exit 0
|
|
240
|
+
;;
|
|
241
|
+
recovering)
|
|
242
|
+
echo "STARTING: Recovering from disk"
|
|
243
|
+
exit 0
|
|
244
|
+
;;
|
|
245
|
+
starting)
|
|
246
|
+
echo "STARTING: Initializing"
|
|
247
|
+
exit 0
|
|
248
|
+
;;
|
|
249
|
+
failed)
|
|
250
|
+
echo "UNHEALTHY: State is failed"
|
|
251
|
+
exit 1
|
|
252
|
+
;;
|
|
253
|
+
*)
|
|
254
|
+
echo "UNKNOWN: State is \$STATE"
|
|
255
|
+
exit 2
|
|
256
|
+
;;
|
|
257
|
+
esac
|
|
258
|
+
`,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
export function getTemplate(config) {
|
|
262
|
+
switch (config.runtime) {
|
|
263
|
+
case 'browser':
|
|
264
|
+
return generateBrowserRuntime(config);
|
|
265
|
+
case 'node':
|
|
266
|
+
return generateNodeRuntime(config);
|
|
267
|
+
case 'self-hosted':
|
|
268
|
+
return generateSelfHostedRuntime(config);
|
|
269
|
+
default:
|
|
270
|
+
throw new Error(`Unknown runtime: ${config.runtime}`);
|
|
271
|
+
}
|
|
272
|
+
}
|
package/dist/index-backend.js
CHANGED
|
@@ -11,7 +11,7 @@ async function loadWasm() {
|
|
|
11
11
|
try {
|
|
12
12
|
// Try to import WASM module
|
|
13
13
|
// @ts-ignore - WASM module is optional and built separately
|
|
14
|
-
const wasmModule = await import('
|
|
14
|
+
const wasmModule = await import('./wasm/feltdb_wasm.js');
|
|
15
15
|
wasmIndexModule = wasmModule;
|
|
16
16
|
wasmAvailable = true;
|
|
17
17
|
return wasmModule;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* }
|
|
26
26
|
* ```
|
|
27
27
|
*/
|
|
28
|
-
import type { JsDb } from '@feltdb/wasm';
|
|
28
|
+
import type { JsDb } from '@feltdb/core/wasm';
|
|
29
29
|
import type { Collection } from '@feltdb/core';
|
|
30
30
|
interface UseFeltDBOptions {
|
|
31
31
|
/** Auto-refresh interval in milliseconds (0 to disable) */
|
package/dist/react/useFeltDB.js
CHANGED
|
@@ -303,7 +303,7 @@ export function withFeltDB(Component, dbPath) {
|
|
|
303
303
|
useEffect(() => {
|
|
304
304
|
try {
|
|
305
305
|
// Dynamically import feltdb module (WASM module)
|
|
306
|
-
import('@feltdb/wasm').then((feltdb) => {
|
|
306
|
+
import('@feltdb/core/wasm').then((feltdb) => {
|
|
307
307
|
setDb(feltdb.open(dbPath));
|
|
308
308
|
}).catch((err) => {
|
|
309
309
|
setDbError(`Failed to load FeltDB: ${err.message}`);
|