@feltdb/core 0.11.2 → 0.11.4

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 (50) hide show
  1. package/README.md +8 -6
  2. package/dist/collection.d.ts +11 -1
  3. package/dist/collection.d.ts.map +1 -1
  4. package/dist/collection.js +34 -5
  5. package/dist/create/package-versions.js +1 -1
  6. package/dist/create/server-source/crates/feltdb/src/lib.rs +31 -30
  7. package/dist/create/server-source/crates/feltdb/src/semantic_decision.rs +1917 -0
  8. package/dist/create/server-source/crates/feltdb/tests/semantic_decision.rs +1165 -0
  9. package/dist/create/server-source/crates/feltdb-server/src/main.rs +232 -95
  10. package/dist/create/server-source/crates/feltdb-wasm/src/lib.rs +73 -8
  11. package/dist/db.d.ts +10 -5
  12. package/dist/db.d.ts.map +1 -1
  13. package/dist/db.js +22 -6
  14. package/dist/embedded-query.d.ts +43 -0
  15. package/dist/embedded-query.d.ts.map +1 -0
  16. package/dist/embedded-query.js +327 -0
  17. package/dist/feltdb.d.ts +5 -1
  18. package/dist/feltdb.d.ts.map +1 -1
  19. package/dist/file-db.d.ts +8 -0
  20. package/dist/file-db.d.ts.map +1 -1
  21. package/dist/file-db.js +24 -0
  22. package/dist/http-db.d.ts +15 -0
  23. package/dist/http-db.d.ts.map +1 -1
  24. package/dist/http-db.js +3 -0
  25. package/dist/index-core.d.ts +2 -0
  26. package/dist/index-core.d.ts.map +1 -1
  27. package/dist/index-core.js +1 -0
  28. package/dist/index-types.d.ts +5 -1
  29. package/dist/index-types.d.ts.map +1 -1
  30. package/dist/indexeddb-db.d.ts +18 -0
  31. package/dist/indexeddb-db.d.ts.map +1 -1
  32. package/dist/indexeddb-db.js +28 -0
  33. package/dist/memory-db.d.ts +8 -0
  34. package/dist/memory-db.d.ts.map +1 -1
  35. package/dist/memory-db.js +19 -0
  36. package/dist/semantic-decision.d.ts +167 -0
  37. package/dist/semantic-decision.d.ts.map +1 -0
  38. package/dist/semantic-decision.js +1 -0
  39. package/dist/studio-app/assets/feltdb_wasm-BGgGSBOP.js +1 -0
  40. package/dist/studio-app/assets/feltdb_wasm_bg-ClM6Qpod.wasm +0 -0
  41. package/dist/studio-app/assets/index-ptUom553.js +30 -0
  42. package/dist/studio-app/index.html +1 -1
  43. package/dist/wasm/feltdb_wasm.d.ts +20 -0
  44. package/dist/wasm/feltdb_wasm.js +91 -0
  45. package/dist/wasm/feltdb_wasm_bg.wasm +0 -0
  46. package/dist/wasm/feltdb_wasm_bg.wasm.d.ts +4 -0
  47. package/package.json +2 -2
  48. package/dist/studio-app/assets/feltdb_wasm-Dlr_kLlk.js +0 -1
  49. package/dist/studio-app/assets/feltdb_wasm_bg-CkozAQKb.wasm +0 -0
  50. package/dist/studio-app/assets/index-H_L5pjur.js +0 -30
package/README.md CHANGED
@@ -136,9 +136,9 @@ A write with `requireAbsent: true` is an atomic create. The authority assigns
136
136
  it `__version: 1`—overriding any caller-supplied version—so it can immediately
137
137
  be updated with `ifVersion: 1`.
138
138
 
139
- ## Bounded authority queries
139
+ ## Bounded queries
140
140
 
141
- Remote databases can filter, order, and limit records inside the authority:
141
+ All runtimes can filter, order, and limit records at their storage boundary:
142
142
 
143
143
  ```typescript
144
144
  const page = await db.query({
@@ -153,10 +153,12 @@ const page = await db.query({
153
153
  });
154
154
  ```
155
155
 
156
- The server adds `recordId` as a deterministic final tie-breaker and returns an
157
- opaque `nextCursor`. Page snapshots are stable across concurrent inserts and
158
- deletes. This method is intentionally unavailable on embedded runtimes;
159
- `Collection.where()` and `Collection.find()` retain their existing behavior.
156
+ FeltDB adds record identity as a deterministic final tie-breaker and returns an
157
+ opaque `nextCursor`. Managed authorities pin page snapshots across concurrent
158
+ writes; embedded runtimes use a query-bound keyset cursor over unchanged
159
+ committed state. Declare compound embedded indexes with `collection.createIndex`
160
+ and inspect selection with `db.explain(query)`. `Collection.find()` retains its
161
+ array result and accepts optional ordering and limit options.
160
162
 
161
163
  ## Durable Operation Management
162
164
 
@@ -12,6 +12,14 @@ import { type FreshnessCapability, type Revision } from './freshness.js';
12
12
  import type { IndexConfig, CollectionQueryPlan } from './index-types.js';
13
13
  export type Predicate<T> = (item: T) => boolean;
14
14
  export type Subscriber<T> = (items: T[]) => void;
15
+ export interface CollectionFindOptions {
16
+ orderBy?: Array<{
17
+ field: string;
18
+ direction: 'asc' | 'desc';
19
+ }>;
20
+ limit?: number;
21
+ cursor?: string;
22
+ }
15
23
  /**
16
24
  * How a refresh decided whether the local cache could be reused.
17
25
  *
@@ -65,6 +73,8 @@ export declare class Collection<T> {
65
73
  private graphUnsubscribe;
66
74
  private runtimeUnsubscribe;
67
75
  private indexBackend;
76
+ /** Declarations include storage-boundary compound indexes not used by the legacy cache index. */
77
+ private declaredIndexes;
68
78
  private indexStore;
69
79
  private indexesLoaded;
70
80
  /** Incremented whenever `cache` is replaced, so the index can tell it is stale. */
@@ -113,7 +123,7 @@ export declare class Collection<T> {
113
123
  *
114
124
  * `lastQueryPlan()` reports which path ran.
115
125
  */
116
- find(query?: Partial<T>): Promise<T[]>;
126
+ find(query?: Partial<T>, options?: CollectionFindOptions): Promise<T[]>;
117
127
  /** Query records by field equality through the canonical application API. */
118
128
  query(query?: Partial<T>): Promise<T[]>;
119
129
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
@@ -46,6 +46,8 @@ export class Collection {
46
46
  graphUnsubscribe = null;
47
47
  runtimeUnsubscribe = null;
48
48
  indexBackend = new IndexBackend();
49
+ /** Declarations include storage-boundary compound indexes not used by the legacy cache index. */
50
+ declaredIndexes = new Map();
49
51
  indexStore;
50
52
  indexesLoaded = false;
51
53
  /** Incremented whenever `cache` is replaced, so the index can tell it is stale. */
@@ -94,7 +96,9 @@ export class Collection {
94
96
  try {
95
97
  const configs = await this.indexStore.loadIndexConfigs();
96
98
  for (const config of configs) {
97
- this.indexBackend.createIndex(config);
99
+ this.declaredIndexes.set(config.name, config);
100
+ if (config.type !== 'compound')
101
+ this.indexBackend.createIndex(config);
98
102
  }
99
103
  this.indexesLoaded = true;
100
104
  }
@@ -129,8 +133,24 @@ export class Collection {
129
133
  *
130
134
  * `lastQueryPlan()` reports which path ran.
131
135
  */
132
- async find(query = {}) {
136
+ async find(query = {}, options) {
133
137
  const entries = Object.entries(query);
138
+ if (options && this.db.authority_query) {
139
+ const page = await this.db.authority_query({
140
+ collection: this.name,
141
+ where: entries.map(([field, eq]) => ({ field, eq })),
142
+ orderBy: options.orderBy,
143
+ limit: options.limit ?? 100,
144
+ cursor: options.cursor,
145
+ });
146
+ this.lastPlan = {
147
+ strategy: page.plan?.index ? 'index' : 'scan',
148
+ ...(page.plan?.index ? { indexName: page.plan.index } : { reason: 'runtime reported no applicable index' }),
149
+ candidatesExamined: page.plan?.actual_rows_scanned ?? page.records.length,
150
+ recordsReturned: page.records.length,
151
+ };
152
+ return page.records;
153
+ }
134
154
  if (entries.length > 0 && this.db.authority_query) {
135
155
  const records = [];
136
156
  let cursor;
@@ -278,7 +298,11 @@ export class Collection {
278
298
  * tasks.createIndex({ name: 'created_idx', type: 'sorted', field: 'createdAt' });
279
299
  */
280
300
  createIndex(config) {
281
- this.indexBackend.createIndex(config);
301
+ if (this.declaredIndexes.has(config.name))
302
+ throw new Error(`Index ${config.name} already exists`);
303
+ this.declaredIndexes.set(config.name, config);
304
+ if (config.type !== 'compound')
305
+ this.indexBackend.createIndex(config);
282
306
  // Index existing data
283
307
  for (const item of this.cache) {
284
308
  const recordId = item?.id || JSON.stringify(item);
@@ -291,14 +315,19 @@ export class Collection {
291
315
  * List all indexes on this collection.
292
316
  */
293
317
  listIndexes() {
294
- return this.indexBackend.listIndexes();
318
+ return [...this.declaredIndexes.values()];
295
319
  }
296
320
  /**
297
321
  * Rebuild all indexes for this collection.
298
322
  * Used to repair corrupted indexes or after data migration.
299
323
  */
300
324
  async rebuildIndexes() {
325
+ await this.db.rebuild_indexes?.();
301
326
  const configs = this.indexBackend.listIndexes();
327
+ // Compound indexes live entirely at the storage boundary and were rebuilt
328
+ // above; there is no reason to materialize this collection for them.
329
+ if (configs.length === 0)
330
+ return;
302
331
  const items = await this.all();
303
332
  for (const item of items) {
304
333
  const recordId = item?.id || JSON.stringify(item);
@@ -311,7 +340,7 @@ export class Collection {
311
340
  * Check if indexes are stale and need rebuilding.
312
341
  */
313
342
  async validateIndexes() {
314
- const configs = this.indexBackend.listIndexes();
343
+ const configs = this.listIndexes();
315
344
  if (configs.length === 0)
316
345
  return true;
317
346
  const items = await this.all();
@@ -1,4 +1,4 @@
1
1
  // One release train keeps generated applications installable. The repository
2
2
  // validation script checks these values against every workspace manifest.
3
- export const FELTDB_PACKAGE_VERSION = '0.11.2';
3
+ export const FELTDB_PACKAGE_VERSION = '0.11.4';
4
4
  export const feltdbPackageRange = `^${FELTDB_PACKAGE_VERSION}`;
@@ -108,6 +108,7 @@ pub mod replica_membership;
108
108
  pub mod replication_manager;
109
109
  pub mod replication_protocol;
110
110
  mod routing;
111
+ pub mod semantic_decision;
111
112
  pub mod sharding;
112
113
  pub mod state_conflict_contract;
113
114
  pub mod state_contract;
@@ -223,6 +224,22 @@ pub use routing::{
223
224
  CapabilityRouter, ExecutionClaim, ExecutionClaimer, ExecutionResultPublisher, PeerStateVersion,
224
225
  RouteDecision,
225
226
  };
227
+ pub use semantic_decision::{
228
+ authorize_context, decide_record, decision_cache_key, deterministic_request_key,
229
+ execute_decision_batch, execute_decision_transport, execute_inline_decision_transport, jev,
230
+ run_choice_diagnostics, run_decision_benchmark, validate_decision_definition,
231
+ validate_decision_result, BinaryDecisionResult, ChoiceDecisionResult, ChoiceDiagnosticsReport,
232
+ ChoiceExpansionObservation, ChoicePermutationObservation, DecisionAuthorizationConfig,
233
+ DecisionAuthorizationDecision, DecisionAuthorizationGate, DecisionBatch, DecisionBatchDecision,
234
+ DecisionBatchEvaluation, DecisionBenchmarkCase, DecisionBenchmarkReport, DecisionContextPacket,
235
+ DecisionDefinition, DecisionError, DecisionEvaluation, DecisionEvidence, DecisionEvidenceField,
236
+ DecisionExecutionMethod, DecisionJudgmentRecord, DecisionKind, DecisionOptions,
237
+ DecisionPrincipal, DecisionProvenance, DecisionRecordRef, DecisionRequest, DecisionResult,
238
+ DecisionRuntime, DecisionRuntimeCapabilities, DecisionRuntimeMetadata, DecisionStateReference,
239
+ DecisionStatus, DecisionTransportAuthorization, DecisionTransportExecutionRequest,
240
+ DecisionTransportExecutionResponse, DecisionTransportRuntime, DeterministicDecisionRuntime,
241
+ ScoreDecisionResult, WeightedOption, DEFAULT_DECISION_COLLECTION,
242
+ };
226
243
  pub use sharding::{
227
244
  HotspotAlert, RebalanceOperation, ShardDistributionSummary, ShardId, ShardKey, ShardManager,
228
245
  ShardMetrics, ShardRange, ShardingStrategy,
@@ -1998,8 +2015,7 @@ impl FeltDb {
1998
2015
  let databases = OPEN_DATABASES.get_or_init(|| Mutex::new(HashMap::new()));
1999
2016
  let mut databases = databases.lock().expect("open database registry poisoned");
2000
2017
  if let Some(open) = databases.get(&path) {
2001
- if let (Some(inner), Some(ownership)) =
2002
- (open.inner.upgrade(), open.ownership.upgrade())
2018
+ if let (Some(inner), Some(ownership)) = (open.inner.upgrade(), open.ownership.upgrade())
2003
2019
  {
2004
2020
  return Ok(Self {
2005
2021
  inner,
@@ -3342,12 +3358,7 @@ impl FeltDb {
3342
3358
  append_event_locked(&mut inner, &row)?;
3343
3359
  let base_revision = inner.authority_revision;
3344
3360
  inner.authority_revision += 1;
3345
- remember_operation_attribution(
3346
- &mut inner,
3347
- &row,
3348
- base_revision,
3349
- base_revision + 1,
3350
- );
3361
+ remember_operation_attribution(&mut inner, &row, base_revision, base_revision + 1);
3351
3362
  inner.put_row(row);
3352
3363
  if let Some(revision) = planned {
3353
3364
  persist_revision_locked(&mut inner, revision)?;
@@ -3428,12 +3439,7 @@ impl FeltDb {
3428
3439
  append_event_locked(&mut inner, &row)?;
3429
3440
  let base_revision = inner.authority_revision;
3430
3441
  inner.authority_revision += 1;
3431
- remember_operation_attribution(
3432
- &mut inner,
3433
- &row,
3434
- base_revision,
3435
- base_revision + 1,
3436
- );
3442
+ remember_operation_attribution(&mut inner, &row, base_revision, base_revision + 1);
3437
3443
  inner.put_row(row);
3438
3444
  if let Some(revision) = planned {
3439
3445
  persist_revision_locked(&mut inner, revision)?;
@@ -5109,15 +5115,12 @@ fn replay_log(inner: &mut Inner) -> Result<()> {
5109
5115
  inner.change_log.observed_versions = header.observed_versions;
5110
5116
  for attribution in header.transaction_history {
5111
5117
  let attribution = normalize_transaction_attribution(attribution);
5112
- inner.authority_revision = inner
5113
- .authority_revision
5114
- .max(attribution.commit_revision);
5115
- inner
5116
- .transaction_revisions
5117
- .insert(
5118
- attribution.transaction_id.clone(),
5119
- (attribution.base_revision, attribution.commit_revision),
5120
- );
5118
+ inner.authority_revision =
5119
+ inner.authority_revision.max(attribution.commit_revision);
5120
+ inner.transaction_revisions.insert(
5121
+ attribution.transaction_id.clone(),
5122
+ (attribution.base_revision, attribution.commit_revision),
5123
+ );
5121
5124
  inner
5122
5125
  .applied_transactions
5123
5126
  .insert(attribution.transaction_id.clone());
@@ -5232,12 +5235,7 @@ fn replay_log(inner: &mut Inner) -> Result<()> {
5232
5235
  let base_revision = inner.authority_revision;
5233
5236
  inner.authority_revision += 1;
5234
5237
  if !snapshot_log {
5235
- remember_operation_attribution(
5236
- inner,
5237
- &row,
5238
- base_revision,
5239
- base_revision + 1,
5240
- );
5238
+ remember_operation_attribution(inner, &row, base_revision, base_revision + 1);
5241
5239
  }
5242
5240
  }
5243
5241
  if let Some(id) = row
@@ -5577,7 +5575,10 @@ mod tests {
5577
5575
  assert_eq!(held, TRANSACTION_ATTRIBUTION_WINDOW);
5578
5576
  let recent = db.recent_transactions(3).expect("attributions");
5579
5577
  assert_eq!(
5580
- recent.iter().map(|value| value.transaction_id.clone()).collect::<Vec<_>>(),
5578
+ recent
5579
+ .iter()
5580
+ .map(|value| value.transaction_id.clone())
5581
+ .collect::<Vec<_>>(),
5581
5582
  vec![
5582
5583
  format!("tx_{}", commits - 1),
5583
5584
  format!("tx_{}", commits - 2),