@feltdb/core 0.7.3 → 0.8.0

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 (147) hide show
  1. package/README.md +25 -0
  2. package/dist/application-development.d.ts +78 -0
  3. package/dist/application-development.d.ts.map +1 -0
  4. package/dist/application-development.js +153 -0
  5. package/dist/application-manifest.d.ts +6 -1
  6. package/dist/application-manifest.d.ts.map +1 -1
  7. package/dist/application-manifest.js +10 -3
  8. package/dist/canonical-application.d.ts +27 -0
  9. package/dist/canonical-application.d.ts.map +1 -0
  10. package/dist/canonical-application.js +46 -0
  11. package/dist/cli/ai-model-config.js +97 -0
  12. package/dist/cli/cli.js +1 -1
  13. package/dist/cli/commands.js +664 -120
  14. package/dist/cli/index.js +1 -1
  15. package/dist/cli/managed-environment.js +6 -0
  16. package/dist/cli/managed-project.js +6 -0
  17. package/dist/cli/proposal-client.js +63 -0
  18. package/dist/cli/publish-engine.js +165 -0
  19. package/dist/cli/source-sync.js +183 -0
  20. package/dist/create/cli.js +11 -2
  21. package/dist/create/create.js +38 -16
  22. package/dist/create/managed-account.js +82 -11
  23. package/dist/create/package-versions.js +1 -1
  24. package/dist/create/server-source/crates/feltdb/src/application.rs +41 -1
  25. package/dist/create/server-source/crates/feltdb/src/authority_failover.rs +84 -6
  26. package/dist/create/server-source/crates/feltdb/src/bin/feltdb_node.rs +126 -38
  27. package/dist/create/server-source/crates/feltdb/src/distributed_transactions.rs +72 -34
  28. package/dist/create/server-source/crates/feltdb/src/lib.rs +20 -2
  29. package/dist/create/server-source/crates/feltdb-server/src/app_state.rs +12 -24
  30. package/dist/create/server-source/crates/feltdb-server/src/application_contract.rs +11 -3
  31. package/dist/create/server-source/crates/feltdb-server/src/authenticated_principal.rs +0 -1
  32. package/dist/create/server-source/crates/feltdb-server/src/certification_harness.rs +23 -22
  33. package/dist/create/server-source/crates/feltdb-server/src/delegation_token.rs +5 -15
  34. package/dist/create/server-source/crates/feltdb-server/src/durable_operations.rs +13 -28
  35. package/dist/create/server-source/crates/feltdb-server/src/identity.rs +111 -3
  36. package/dist/create/server-source/crates/feltdb-server/src/key_management.rs +28 -7
  37. package/dist/create/server-source/crates/feltdb-server/src/lib.rs +5 -5
  38. package/dist/create/server-source/crates/feltdb-server/src/main.rs +1960 -143
  39. package/dist/create/server-source/crates/feltdb-server/src/managed_diagnostics.rs +10 -30
  40. package/dist/create/server-source/crates/feltdb-server/src/membership_policy.rs +12 -4
  41. package/dist/create/server-source/crates/feltdb-server/src/request_telemetry.rs +8 -6
  42. package/dist/create/server-source/crates/feltdb-server/src/snapshot_cursor.rs +10 -14
  43. package/dist/create/server-source/crates/feltdb-server/src/tenancy.rs +195 -13
  44. package/dist/create/server-source/crates/feltdb-server/src/tenant_policies.rs +9 -21
  45. package/dist/create/server-source/crates/feltdb-server/src/transaction_idempotency.rs +5 -3
  46. package/dist/create/server-source/crates/feltdb-server/src/transaction_recovery.rs +9 -8
  47. package/dist/create/server-source/crates/feltdb-server/tests/revision_recovery_integration_test.rs +1 -4
  48. package/dist/create/template/default-project/README.md +57 -0
  49. package/dist/create/template/default-project/agents/activity-assistant.ts +18 -0
  50. package/dist/create/template/default-project/agents/project-assistant.ts +19 -0
  51. package/dist/create/template/default-project/capabilities/activity-summary.ts +14 -0
  52. package/dist/create/template/default-project/capabilities/project-search.ts +16 -0
  53. package/dist/create/template/default-project/capabilities/project-summary.ts +15 -0
  54. package/dist/create/template/default-project/feltdb.flow +174 -0
  55. package/dist/create/template/default-project/src/App.tsx +20 -0
  56. package/dist/create/template/default-project/src/context/AuthContext.tsx +27 -0
  57. package/dist/create/template/default-project/src/feltdb.ts +87 -0
  58. package/dist/create/template/default-project/src/index.tsx +14 -0
  59. package/dist/create/template/default-project/src/pages/Activity.tsx +7 -0
  60. package/dist/create/template/default-project/src/pages/Agents.tsx +15 -0
  61. package/dist/create/template/default-project/src/pages/Dashboard.tsx +17 -0
  62. package/dist/create/template/default-project/src/pages/Invitations.tsx +11 -0
  63. package/dist/create/template/default-project/src/pages/Projects.tsx +11 -0
  64. package/dist/create/template/default-project/src/pages/SignIn.tsx +8 -0
  65. package/dist/create/template/default-project/src/pages/SignUp.tsx +8 -0
  66. package/dist/create/template/default-project/src/styles-application.css +21 -0
  67. package/dist/create/template/default-project/src/styles.css +1 -0
  68. package/dist/create/template/default-project/workflows/agent-assisted-summary.ts +1 -0
  69. package/dist/create/template/default-project/workflows/invitation.ts +30 -0
  70. package/dist/create/template/default-project/workflows/project-created.ts +2 -0
  71. package/dist/db.d.ts +49 -1
  72. package/dist/db.d.ts.map +1 -1
  73. package/dist/db.js +77 -0
  74. package/dist/error-codes.d.ts +20 -1
  75. package/dist/error-codes.d.ts.map +1 -1
  76. package/dist/error-codes.js +25 -0
  77. package/dist/flowspec.d.ts +1 -0
  78. package/dist/flowspec.d.ts.map +1 -1
  79. package/dist/flowspec.js +66 -11
  80. package/dist/http-client.d.ts +135 -14
  81. package/dist/http-client.d.ts.map +1 -1
  82. package/dist/http-client.js +79 -31
  83. package/dist/http-db.d.ts +15 -2
  84. package/dist/http-db.d.ts.map +1 -1
  85. package/dist/http-db.js +113 -5
  86. package/dist/index-core.d.ts +5 -0
  87. package/dist/index-core.d.ts.map +1 -1
  88. package/dist/index-core.js +5 -0
  89. package/dist/module-intent.d.ts +37 -0
  90. package/dist/module-intent.d.ts.map +1 -0
  91. package/dist/module-intent.js +81 -0
  92. package/dist/module.d.ts +76 -0
  93. package/dist/module.d.ts.map +1 -0
  94. package/dist/module.js +61 -0
  95. package/dist/proposal.d.ts +161 -0
  96. package/dist/proposal.d.ts.map +1 -0
  97. package/dist/proposal.js +232 -0
  98. package/dist/studio/app.d.ts +5 -1
  99. package/dist/studio/app.d.ts.map +1 -1
  100. package/dist/studio/components/ApplicationDesigner.d.ts +2 -1
  101. package/dist/studio/components/ApplicationDesigner.d.ts.map +1 -1
  102. package/dist/studio/components/AskFeltDB.d.ts +21 -0
  103. package/dist/studio/components/AskFeltDB.d.ts.map +1 -0
  104. package/dist/studio/components/ContractInspector.d.ts +7 -0
  105. package/dist/studio/components/ContractInspector.d.ts.map +1 -0
  106. package/dist/studio/components/ManagedInstancePanel.d.ts.map +1 -1
  107. package/dist/studio/components/ManagedInstancePanel.js +1 -5
  108. package/dist/studio/components/ModuleExplorer.d.ts +6 -0
  109. package/dist/studio/components/ModuleExplorer.d.ts.map +1 -0
  110. package/dist/studio/components/ProposalBrowser.d.ts +12 -0
  111. package/dist/studio/components/ProposalBrowser.d.ts.map +1 -0
  112. package/dist/studio/components/StateExplorer.d.ts +6 -7
  113. package/dist/studio/components/StateExplorer.d.ts.map +1 -1
  114. package/dist/studio/components/index.d.ts +4 -0
  115. package/dist/studio/components/index.d.ts.map +1 -1
  116. package/dist/studio/components/index.js +4 -4
  117. package/dist/studio/components-CNSNrmA9.js +2787 -0
  118. package/dist/studio/index.js +214 -157
  119. package/dist/studio/studio.css +1 -1
  120. package/dist/studio/utils/index.d.ts +2 -0
  121. package/dist/studio/utils/index.d.ts.map +1 -1
  122. package/dist/studio/utils/index.js +14 -12
  123. package/dist/studio/utils/managed-instance.d.ts +0 -4
  124. package/dist/studio/utils/managed-instance.d.ts.map +1 -1
  125. package/dist/studio/utils/managed-instance.js +0 -4
  126. package/dist/studio/utils/proposal-api.d.ts +53 -0
  127. package/dist/studio/utils/proposal-api.d.ts.map +1 -0
  128. package/dist/studio/utils/proposal-api.js +91 -0
  129. package/dist/studio/utils/service-api.d.ts +81 -0
  130. package/dist/studio/utils/service-api.d.ts.map +1 -0
  131. package/dist/studio/utils/service-api.js +51 -0
  132. package/dist/studio-app/assets/dist-CCOk39Uc.js +1 -0
  133. package/dist/studio-app/assets/{feltdb_wasm-DVKsw75S.js → feltdb_wasm-CSB6KVgw.js} +1 -1
  134. package/dist/studio-app/assets/feltdb_wasm_bg-Dd1fnO9U.wasm +0 -0
  135. package/dist/studio-app/assets/index-Bncji3aN.js +43 -0
  136. package/dist/studio-app/assets/{index-C1GWyazR.css → index-yazaWMUN.css} +1 -1
  137. package/dist/studio-app/assets/lib-B2_7fcn7.js +69 -0
  138. package/dist/studio-app/assets/worker-CARZ5g7K.js +69 -0
  139. package/dist/studio-app/index.html +2 -2
  140. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  141. package/dist/workspace/local-development-authority.d.ts +3 -0
  142. package/dist/workspace/local-development-authority.d.ts.map +1 -1
  143. package/dist/workspace/local-development-authority.js +124 -2
  144. package/package.json +1 -1
  145. package/dist/studio/components-Dxuhrv8_.js +0 -1832
  146. package/dist/studio-app/assets/feltdb_wasm_bg-DNyNf0yy.wasm +0 -0
  147. package/dist/studio-app/assets/index-B5tnmvSD.js +0 -28
@@ -1,3 +1,3 @@
1
- <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-B5tnmvSD.js"></script>
2
- <link rel="stylesheet" crossorigin href="/assets/index-C1GWyazR.css">
1
+ <!doctype html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#17211b"/><title>FeltDB Studio</title> <script type="module" crossorigin src="/assets/index-Bncji3aN.js"></script>
2
+ <link rel="stylesheet" crossorigin href="/assets/index-yazaWMUN.css">
3
3
  </head><body><div id="root"></div></body></html>
Binary file
@@ -1,11 +1,14 @@
1
+ import { type ProposalContext } from '../proposal.js';
1
2
  export interface LocalDevelopmentAuthority {
2
3
  endpoint: string;
4
+ proposalAuthorityToken: string;
3
5
  close(): Promise<void>;
4
6
  }
5
7
  export interface LocalDevelopmentAuthorityOptions {
6
8
  dataDir: string;
7
9
  host?: string;
8
10
  port?: number;
11
+ proposalContext?: () => Promise<ProposalContext>;
9
12
  }
10
13
  /** Start the durable, unauthenticated loopback authority used by `feltdb dev`. */
11
14
  export declare function startLocalDevelopmentAuthority(options: LocalDevelopmentAuthorityOptions): Promise<LocalDevelopmentAuthority>;
@@ -1 +1 @@
1
- {"version":3,"file":"local-development-authority.d.ts","sourceRoot":"","sources":["../../src/workspace/local-development-authority.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,kFAAkF;AAClF,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAyFpC"}
1
+ {"version":3,"file":"local-development-authority.d.ts","sourceRoot":"","sources":["../../src/workspace/local-development-authority.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,eAAe,EAAsB,MAAM,gBAAgB,CAAC;AAEjG,MAAM,WAAW,yBAAyB;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,gCAAgC;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CAClD;AAED,kFAAkF;AAClF,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,yBAAyB,CAAC,CAoJpC"}
@@ -1,6 +1,7 @@
1
1
  import http from 'node:http';
2
2
  import path from 'node:path';
3
3
  import { FileJsDb } from '../file-db.js';
4
+ import { FeltDBProposalService } from '../proposal.js';
4
5
  /** Start the durable, unauthenticated loopback authority used by `feltdb dev`. */
5
6
  export async function startLocalDevelopmentAuthority(options) {
6
7
  const host = options.host || '127.0.0.1';
@@ -9,19 +10,32 @@ export async function startLocalDevelopmentAuthority(options) {
9
10
  throw new Error('The development authority may only bind to a loopback address');
10
11
  }
11
12
  const db = new FileJsDb(path.resolve(options.dataDir));
13
+ const proposalAuthorityToken = crypto.randomUUID();
14
+ const store = {
15
+ async get(collection, id) { const result = db.get(`${collection}:${id}`); if (!result.success)
16
+ throw new Error(result.error); return result.data ? JSON.parse(result.data) : undefined; },
17
+ async list(collection) { const result = db.query(collection); if (!result.success)
18
+ throw new Error(result.error); return JSON.parse(result.data || '[]'); },
19
+ async create(collection, id, value) { const result = db.insert(`${collection}:${id}`, JSON.stringify(value)); if (!result.success)
20
+ throw new Error(result.error); },
21
+ async replace(collection, id, value) { const result = db.update(`${collection}:${id}`, JSON.stringify(value)); if (!result.success)
22
+ throw new Error(result.error); },
23
+ };
24
+ const proposalService = options.proposalContext ? new FeltDBProposalService(store, options.proposalContext, proposalAuthorityToken) : undefined;
12
25
  const streams = new Set();
13
26
  const server = http.createServer(async (request, response) => {
14
27
  try {
15
28
  response.setHeader('Access-Control-Allow-Origin', '*');
16
29
  response.setHeader('Access-Control-Allow-Methods', 'GET, POST, PATCH, DELETE, OPTIONS');
17
- response.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type, FeltDB-Protocol');
30
+ response.setHeader('Access-Control-Allow-Headers', 'Authorization, Content-Type, FeltDB-Protocol, FeltDB-Proposal-Authority');
18
31
  response.setHeader('Cache-Control', 'no-store');
19
32
  if (request.method === 'OPTIONS') {
20
33
  response.statusCode = 204;
21
34
  response.end();
22
35
  return;
23
36
  }
24
- const pathname = new URL(request.url || '/', `http://${host}`).pathname;
37
+ const requestUrl = new URL(request.url || '/', `http://${host}`);
38
+ const pathname = requestUrl.pathname;
25
39
  if (request.method === 'GET' && (pathname === '/health' || pathname === '/ready')) {
26
40
  json(response, 200, { status: 'ready', storage: 'writable', authority: 'local-development' });
27
41
  return;
@@ -38,12 +52,119 @@ export async function startLocalDevelopmentAuthority(options) {
38
52
  request.once('close', () => streams.delete(response));
39
53
  return;
40
54
  }
55
+ const previewSimulationMatch = pathname.match(/^\/v1\/previews\/([^/]+)\/simulate$/);
56
+ if (previewSimulationMatch) {
57
+ if (!proposalService) {
58
+ json(response, 503, { error: 'PROPOSAL_SERVICE_UNAVAILABLE' });
59
+ return;
60
+ }
61
+ if (request.method !== 'POST') {
62
+ json(response, 405, { error: 'METHOD_NOT_ALLOWED' });
63
+ return;
64
+ }
65
+ const artifact = await proposalService.getPreview(decodeURIComponent(previewSimulationMatch[1]));
66
+ const input = parseObject(await readBody(request));
67
+ const event = String(input.event || '');
68
+ if (!artifact.events.includes(event)) {
69
+ json(response, 422, { error: 'UNSUPPORTED_PREVIEW_EVENT' });
70
+ return;
71
+ }
72
+ json(response, 200, { preview_id: artifact.preview_id, event, status: 'simulated', external_side_effects: 'none', trace: artifact.state_flow, writes: 'isolated_preview_namespace_only' });
73
+ return;
74
+ }
75
+ const previewMatch = pathname.match(/^\/v1\/previews\/([^/]+)(?:\/data\/([^/]+))?$/);
76
+ if (previewMatch) {
77
+ if (!proposalService) {
78
+ json(response, 503, { error: 'PROPOSAL_SERVICE_UNAVAILABLE' });
79
+ return;
80
+ }
81
+ const artifact = await proposalService.getPreview(decodeURIComponent(previewMatch[1]));
82
+ if (request.method === 'GET' && !previewMatch[2]) {
83
+ json(response, 200, artifact);
84
+ return;
85
+ }
86
+ if (request.method === 'GET' && previewMatch[2]) {
87
+ const collection = decodeURIComponent(previewMatch[2]);
88
+ const seed = artifact.seeded_records.find(value => value.collection === collection);
89
+ json(response, seed ? 200 : 404, seed ? { preview_id: artifact.preview_id, collection, records: [{ id: seed.id, _preview_data: true, _preview_source: 'synthetic' }], data_classification: 'synthetic_preview', pagination: { limit: 50, nextCursor: null } } : { error: 'COLLECTION_NOT_FOUND' });
90
+ return;
91
+ }
92
+ json(response, 405, { error: 'METHOD_NOT_ALLOWED' });
93
+ return;
94
+ }
95
+ const proposalMatch = pathname.match(/^\/v1\/proposals(?:\/([^/]+)(?:\/(validate|preview|approve|reject|status|history))?)?$/);
96
+ if (proposalMatch) {
97
+ if (!proposalService) {
98
+ json(response, 503, { error: 'PROPOSAL_SERVICE_UNAVAILABLE' });
99
+ return;
100
+ }
101
+ const id = proposalMatch[1] ? decodeURIComponent(proposalMatch[1]) : undefined;
102
+ const operation = proposalMatch[2];
103
+ const body = await readBody(request);
104
+ const input = body ? parseObject(body) : {};
105
+ const actor = typeof input.actor === 'string' ? input.actor : 'local-developer';
106
+ if (request.method === 'POST' && !id) {
107
+ json(response, 201, await proposalService.create(input));
108
+ return;
109
+ }
110
+ if (request.method === 'GET' && !id) {
111
+ const limit = Math.max(1, Math.min(100, Number(requestUrl.searchParams.get('limit') || 50)));
112
+ const status = requestUrl.searchParams.get('status');
113
+ const environment = requestUrl.searchParams.get('environment');
114
+ const after = requestUrl.searchParams.get('cursor');
115
+ const offset = after ? Number(Buffer.from(after, 'base64url').toString('utf8')) : 0;
116
+ const all = (await proposalService.list()).filter(value => (!status || value.status === status) && (!environment || value.environment === environment)).sort((a, b) => a.id.localeCompare(b.id));
117
+ const proposals = all.slice(offset, offset + limit);
118
+ const nextCursor = offset + limit < all.length ? Buffer.from(String(offset + limit)).toString('base64url') : null;
119
+ json(response, 200, { proposals, pagination: { limit, nextCursor } });
120
+ return;
121
+ }
122
+ if (request.method === 'GET' && id && !operation) {
123
+ json(response, 200, await proposalService.get(id));
124
+ return;
125
+ }
126
+ if (request.method === 'GET' && id && operation === 'history') {
127
+ json(response, 200, { events: await proposalService.history(id) });
128
+ return;
129
+ }
130
+ if (request.method === 'GET' && id && operation === 'status') {
131
+ json(response, 200, await proposalService.readiness(id));
132
+ return;
133
+ }
134
+ if (request.method === 'POST' && id && operation === 'validate') {
135
+ json(response, 200, await proposalService.validate(id, actor));
136
+ return;
137
+ }
138
+ if (request.method === 'POST' && id && operation === 'preview') {
139
+ json(response, 200, await proposalService.preview(id, actor));
140
+ return;
141
+ }
142
+ if (request.method === 'POST' && id && operation === 'approve') {
143
+ json(response, 200, await proposalService.transition(id, 'approved', actor, undefined, input.approve_authorization === true));
144
+ return;
145
+ }
146
+ if (request.method === 'POST' && id && operation === 'reject') {
147
+ json(response, 200, await proposalService.transition(id, 'rejected', actor));
148
+ return;
149
+ }
150
+ if (request.method === 'PATCH' && id && operation === 'status') {
151
+ const status = String(input.status || '');
152
+ json(response, 200, await proposalService.transition(id, status, actor, request.headers['feltdb-proposal-authority'], input.approve_authorization === true));
153
+ return;
154
+ }
155
+ json(response, 405, { error: 'METHOD_NOT_ALLOWED' });
156
+ return;
157
+ }
41
158
  const match = pathname.match(/^\/collections\/([^/]+)(?:\/([^/]+))?$/);
42
159
  if (!match) {
43
160
  json(response, 404, { error: 'NOT_FOUND' });
44
161
  return;
45
162
  }
46
163
  const collection = decodeURIComponent(match[1]);
164
+ if (collection.startsWith('_feltdb.')) {
165
+ json(response, 403, { error: 'SYSTEM_COLLECTION_REQUIRES_SERVICE_API' });
166
+ return;
167
+ }
47
168
  const id = match[2] ? decodeURIComponent(match[2]) : undefined;
48
169
  const body = await readBody(request);
49
170
  let result;
@@ -108,6 +229,7 @@ export async function startLocalDevelopmentAuthority(options) {
108
229
  });
109
230
  return {
110
231
  endpoint: `http://${host}:${port}`,
232
+ proposalAuthorityToken,
111
233
  close: () => new Promise((resolve, reject) => {
112
234
  for (const stream of streams)
113
235
  stream.end();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feltdb/core",
3
- "version": "0.7.3",
3
+ "version": "0.8.0",
4
4
  "description": "FeltDB Core - Application-facing database with Browser, Local, and Server runtimes. Durable state, reactive APIs.",
5
5
  "license": "MIT",
6
6
  "type": "module",