@durable-streams/state 0.2.3 → 0.2.5

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 CHANGED
@@ -353,10 +353,12 @@ const db = createStreamDB({
353
353
  const txid = crypto.randomUUID()
354
354
 
355
355
  await stream.append(
356
- schema.users.insert({
357
- value: user,
358
- headers: { txid },
359
- })
356
+ JSON.stringify(
357
+ schema.users.insert({
358
+ value: user,
359
+ headers: { txid },
360
+ })
361
+ )
360
362
  )
361
363
 
362
364
  // Wait for confirmation
@@ -375,11 +377,13 @@ const db = createStreamDB({
375
377
  const current = await db.collections.users.get(id)
376
378
 
377
379
  await stream.append(
378
- schema.users.update({
379
- value: { ...current, ...updates },
380
- oldValue: current,
381
- headers: { txid },
382
- })
380
+ JSON.stringify(
381
+ schema.users.update({
382
+ value: { ...current, ...updates },
383
+ oldValue: current,
384
+ headers: { txid },
385
+ })
386
+ )
383
387
  )
384
388
 
385
389
  await db.utils.awaitTxId(txid)
@@ -462,9 +466,11 @@ const schema = createStateSchema({
462
466
 
463
467
  // Set value
464
468
  await stream.append(
465
- schema.config.insert({
466
- value: { key: "theme", value: "dark" },
467
- })
469
+ JSON.stringify(
470
+ schema.config.insert({
471
+ value: { key: "theme", value: "dark" },
472
+ })
473
+ )
468
474
  )
469
475
 
470
476
  // Query value reactively
@@ -489,13 +495,15 @@ const schema = createStateSchema({
489
495
 
490
496
  // Update presence
491
497
  await stream.append(
492
- schema.presence.update({
493
- value: {
494
- userId: "kyle",
495
- status: "online",
496
- lastSeen: Date.now(),
497
- },
498
- })
498
+ JSON.stringify(
499
+ schema.presence.update({
500
+ value: {
501
+ userId: "kyle",
502
+ status: "online",
503
+ lastSeen: Date.now(),
504
+ },
505
+ })
506
+ )
499
507
  )
500
508
 
501
509
  // Query presence with TanStack DB
package/dist/index.cjs CHANGED
@@ -461,12 +461,6 @@ function createStreamDB(options) {
461
461
  startSync: true,
462
462
  gcTime: 0
463
463
  });
464
- console.log(`[StreamDB] Created collection "${name}":`, {
465
- type: typeof collection,
466
- constructor: collection.constructor.name,
467
- isCollection: collection instanceof Object,
468
- hasSize: `size` in collection
469
- });
470
464
  collectionInstances[name] = collection;
471
465
  }
472
466
  let streamResponse = null;
@@ -482,21 +476,11 @@ function createStreamDB(options) {
482
476
  live: true,
483
477
  signal: abortController.signal
484
478
  });
485
- let batchCount = 0;
486
- let lastBatchTime = Date.now();
487
479
  streamResponse.subscribeJson((batch) => {
488
480
  try {
489
- batchCount++;
490
- lastBatchTime = Date.now();
491
- if (batch.items.length > 0) console.log(`[StreamDB] Processing batch #${batchCount}: ${batch.items.length} items, upToDate=${batch.upToDate}`);
492
481
  for (const event of batch.items) if (isChangeEvent(event)) dispatcher.dispatchChange(event);
493
482
  else if (isControlEvent(event)) dispatcher.dispatchControl(event);
494
- if (batch.upToDate) {
495
- console.log(`[StreamDB] Marking up-to-date after batch #${batchCount}`);
496
- dispatcher.markUpToDate();
497
- console.log(`[StreamDB] Successfully marked up-to-date`);
498
- }
499
- if (batch.items.length > 0) console.log(`[StreamDB] Successfully processed batch #${batchCount}`);
483
+ if (batch.upToDate) dispatcher.markUpToDate();
500
484
  } catch (error) {
501
485
  console.error(`[StreamDB] Error processing batch:`, error);
502
486
  console.error(`[StreamDB] Failed batch:`, batch);
@@ -505,14 +489,6 @@ function createStreamDB(options) {
505
489
  }
506
490
  return Promise.resolve();
507
491
  });
508
- const healthCheck = setInterval(() => {
509
- const timeSinceLastBatch = Date.now() - lastBatchTime;
510
- console.log(`[StreamDB] Health: ${batchCount} batches processed, last batch ${(timeSinceLastBatch / 1e3).toFixed(1)}s ago`);
511
- }, 15e3);
512
- abortController.signal.addEventListener(`abort`, () => {
513
- clearInterval(healthCheck);
514
- console.log(`[StreamDB] Aborted - cleaning up health check`);
515
- });
516
492
  };
517
493
  const dbMethods = {
518
494
  stream,
@@ -526,13 +502,10 @@ function createStreamDB(options) {
526
502
  },
527
503
  utils: { awaitTxId: (txid, timeout) => dispatcher.awaitTxId(txid, timeout) }
528
504
  };
529
- console.log(`[StreamDB] Creating db object with collections:`, Object.keys(collectionInstances));
530
505
  const db = {
531
506
  collections: collectionInstances,
532
507
  ...dbMethods
533
508
  };
534
- console.log(`[StreamDB] db.collections:`, Object.keys(db.collections));
535
- console.log(`[StreamDB] db.collections.events:`, db.collections.events);
536
509
  if (actionsFactory) {
537
510
  const actionDefs = actionsFactory({
538
511
  db,
package/dist/index.js CHANGED
@@ -437,12 +437,6 @@ function createStreamDB(options) {
437
437
  startSync: true,
438
438
  gcTime: 0
439
439
  });
440
- console.log(`[StreamDB] Created collection "${name}":`, {
441
- type: typeof collection,
442
- constructor: collection.constructor.name,
443
- isCollection: collection instanceof Object,
444
- hasSize: `size` in collection
445
- });
446
440
  collectionInstances[name] = collection;
447
441
  }
448
442
  let streamResponse = null;
@@ -458,21 +452,11 @@ function createStreamDB(options) {
458
452
  live: true,
459
453
  signal: abortController.signal
460
454
  });
461
- let batchCount = 0;
462
- let lastBatchTime = Date.now();
463
455
  streamResponse.subscribeJson((batch) => {
464
456
  try {
465
- batchCount++;
466
- lastBatchTime = Date.now();
467
- if (batch.items.length > 0) console.log(`[StreamDB] Processing batch #${batchCount}: ${batch.items.length} items, upToDate=${batch.upToDate}`);
468
457
  for (const event of batch.items) if (isChangeEvent(event)) dispatcher.dispatchChange(event);
469
458
  else if (isControlEvent(event)) dispatcher.dispatchControl(event);
470
- if (batch.upToDate) {
471
- console.log(`[StreamDB] Marking up-to-date after batch #${batchCount}`);
472
- dispatcher.markUpToDate();
473
- console.log(`[StreamDB] Successfully marked up-to-date`);
474
- }
475
- if (batch.items.length > 0) console.log(`[StreamDB] Successfully processed batch #${batchCount}`);
459
+ if (batch.upToDate) dispatcher.markUpToDate();
476
460
  } catch (error) {
477
461
  console.error(`[StreamDB] Error processing batch:`, error);
478
462
  console.error(`[StreamDB] Failed batch:`, batch);
@@ -481,14 +465,6 @@ function createStreamDB(options) {
481
465
  }
482
466
  return Promise.resolve();
483
467
  });
484
- const healthCheck = setInterval(() => {
485
- const timeSinceLastBatch = Date.now() - lastBatchTime;
486
- console.log(`[StreamDB] Health: ${batchCount} batches processed, last batch ${(timeSinceLastBatch / 1e3).toFixed(1)}s ago`);
487
- }, 15e3);
488
- abortController.signal.addEventListener(`abort`, () => {
489
- clearInterval(healthCheck);
490
- console.log(`[StreamDB] Aborted - cleaning up health check`);
491
- });
492
468
  };
493
469
  const dbMethods = {
494
470
  stream,
@@ -502,13 +478,10 @@ function createStreamDB(options) {
502
478
  },
503
479
  utils: { awaitTxId: (txid, timeout) => dispatcher.awaitTxId(txid, timeout) }
504
480
  };
505
- console.log(`[StreamDB] Creating db object with collections:`, Object.keys(collectionInstances));
506
481
  const db = {
507
482
  collections: collectionInstances,
508
483
  ...dbMethods
509
484
  };
510
- console.log(`[StreamDB] db.collections:`, Object.keys(db.collections));
511
- console.log(`[StreamDB] db.collections.events:`, db.collections.events);
512
485
  if (actionsFactory) {
513
486
  const actionDefs = actionsFactory({
514
487
  db,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@durable-streams/state",
3
3
  "description": "State change event protocol for Durable Streams",
4
- "version": "0.2.3",
4
+ "version": "0.2.5",
5
5
  "author": "Durable Stream contributors",
6
6
  "license": "Apache-2.0",
7
7
  "repository": {
@@ -59,7 +59,7 @@
59
59
  "@tanstack/db": "latest",
60
60
  "@tanstack/intent": "latest",
61
61
  "tsdown": "^0.9.0",
62
- "@durable-streams/server": "0.2.3"
62
+ "@durable-streams/server": "0.3.1"
63
63
  },
64
64
  "engines": {
65
65
  "node": ">=18.0.0"
@@ -77,22 +77,34 @@ const messages = db.collections.messages
77
77
 
78
78
  ### Reactive queries with TanStack DB
79
79
 
80
- StreamDB collections are TanStack DB collections. Use framework adapters for reactive queries:
80
+ StreamDB collections are TanStack DB collections. Use framework adapters for reactive queries.
81
+
82
+ **IMPORTANT**: `useLiveQuery` returns `{ data }`, NOT the array directly. Always destructure with a default:
81
83
 
82
84
  ```typescript
83
85
  import { useLiveQuery } from "@tanstack/react-db"
84
86
  import { eq } from "@durable-streams/state"
85
87
 
88
+ // List query — destructure { data } with a default empty array
89
+ function UserList() {
90
+ const { data: users = [] } = useLiveQuery((q) =>
91
+ q.from({ users: db.collections.users })
92
+ )
93
+
94
+ return users.map(u => <div key={u.id}>{u.name}</div>)
95
+ }
96
+
97
+ // Single item query — use findOne(), data is T | undefined
86
98
  function UserProfile({ userId }: { userId: string }) {
87
- const userQuery = useLiveQuery((q) =>
99
+ const { data: user } = useLiveQuery((q) =>
88
100
  q
89
101
  .from({ users: db.collections.users })
90
102
  .where(({ users }) => eq(users.id, userId))
91
103
  .findOne()
92
104
  )
93
105
 
94
- if (!userQuery.data) return null
95
- return <div>{userQuery.data.name}</div>
106
+ if (!user) return null
107
+ return <div>{user.name}</div>
96
108
  }
97
109
  ```
98
110
 
package/src/stream-db.ts CHANGED
@@ -790,13 +790,6 @@ export function createStreamDB<
790
790
  gcTime: 0,
791
791
  })
792
792
 
793
- console.log(`[StreamDB] Created collection "${name}":`, {
794
- type: typeof collection,
795
- constructor: collection.constructor.name,
796
- isCollection: collection instanceof Object,
797
- hasSize: `size` in collection,
798
- })
799
-
800
793
  collectionInstances[name] = collection
801
794
  }
802
795
 
@@ -818,22 +811,9 @@ export function createStreamDB<
818
811
  signal: abortController.signal,
819
812
  })
820
813
 
821
- // Track batch processing for debugging
822
- let batchCount = 0
823
- let lastBatchTime = Date.now()
824
-
825
814
  // Process events as they come in
826
815
  streamResponse.subscribeJson((batch) => {
827
816
  try {
828
- batchCount++
829
- lastBatchTime = Date.now()
830
-
831
- if (batch.items.length > 0) {
832
- console.log(
833
- `[StreamDB] Processing batch #${batchCount}: ${batch.items.length} items, upToDate=${batch.upToDate}`
834
- )
835
- }
836
-
837
817
  for (const event of batch.items) {
838
818
  if (isChangeEvent(event)) {
839
819
  dispatcher.dispatchChange(event)
@@ -844,15 +824,7 @@ export function createStreamDB<
844
824
 
845
825
  // Check batch-level up-to-date signal
846
826
  if (batch.upToDate) {
847
- console.log(
848
- `[StreamDB] Marking up-to-date after batch #${batchCount}`
849
- )
850
827
  dispatcher.markUpToDate()
851
- console.log(`[StreamDB] Successfully marked up-to-date`)
852
- }
853
-
854
- if (batch.items.length > 0) {
855
- console.log(`[StreamDB] Successfully processed batch #${batchCount}`)
856
828
  }
857
829
  } catch (error) {
858
830
  console.error(`[StreamDB] Error processing batch:`, error)
@@ -865,20 +837,6 @@ export function createStreamDB<
865
837
  }
866
838
  return Promise.resolve()
867
839
  })
868
-
869
- // Health check to detect silent stalls
870
- const healthCheck = setInterval(() => {
871
- const timeSinceLastBatch = Date.now() - lastBatchTime
872
- console.log(
873
- `[StreamDB] Health: ${batchCount} batches processed, last batch ${(timeSinceLastBatch / 1000).toFixed(1)}s ago`
874
- )
875
- }, 15000)
876
-
877
- // Clean up health check on abort
878
- abortController.signal.addEventListener(`abort`, () => {
879
- clearInterval(healthCheck)
880
- console.log(`[StreamDB] Aborted - cleaning up health check`)
881
- })
882
840
  }
883
841
 
884
842
  // Build the StreamDB object with methods
@@ -900,16 +858,10 @@ export function createStreamDB<
900
858
  }
901
859
 
902
860
  // Combine collections with methods
903
- console.log(
904
- `[StreamDB] Creating db object with collections:`,
905
- Object.keys(collectionInstances)
906
- )
907
861
  const db = {
908
862
  collections: collectionInstances,
909
863
  ...dbMethods,
910
864
  } as unknown as StreamDB<TDef>
911
- console.log(`[StreamDB] db.collections:`, Object.keys(db.collections))
912
- console.log(`[StreamDB] db.collections.events:`, db.collections.events)
913
865
 
914
866
  // If actions factory is provided, wrap actions and return db with actions
915
867
  if (actionsFactory) {