spacetimedb 2.0.4 → 2.1.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 (64) hide show
  1. package/LICENSE.txt +2 -2
  2. package/dist/angular/index.cjs +2 -1
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.mjs +2 -1
  5. package/dist/angular/index.mjs.map +1 -1
  6. package/dist/browser/angular/index.mjs +2 -1
  7. package/dist/browser/angular/index.mjs.map +1 -1
  8. package/dist/browser/react/index.mjs +5 -1
  9. package/dist/browser/react/index.mjs.map +1 -1
  10. package/dist/browser/svelte/index.mjs +2 -1
  11. package/dist/browser/svelte/index.mjs.map +1 -1
  12. package/dist/browser/vue/index.mjs +2 -1
  13. package/dist/browser/vue/index.mjs.map +1 -1
  14. package/dist/index.browser.mjs +22 -8
  15. package/dist/index.browser.mjs.map +1 -1
  16. package/dist/index.cjs +22 -8
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.mjs +22 -8
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/lib/algebraic_type.d.ts.map +1 -1
  21. package/dist/lib/query.d.ts +10 -5
  22. package/dist/lib/query.d.ts.map +1 -1
  23. package/dist/lib/table.d.ts +6 -1
  24. package/dist/lib/table.d.ts.map +1 -1
  25. package/dist/min/index.browser.mjs +1 -1
  26. package/dist/min/index.browser.mjs.map +1 -1
  27. package/dist/min/react/index.mjs +1 -1
  28. package/dist/min/react/index.mjs.map +1 -1
  29. package/dist/min/sdk/index.browser.mjs +1 -1
  30. package/dist/min/sdk/index.browser.mjs.map +1 -1
  31. package/dist/react/index.cjs +5 -1
  32. package/dist/react/index.cjs.map +1 -1
  33. package/dist/react/index.mjs +5 -1
  34. package/dist/react/index.mjs.map +1 -1
  35. package/dist/react/useTable.d.ts.map +1 -1
  36. package/dist/sdk/index.browser.mjs +18 -6
  37. package/dist/sdk/index.browser.mjs.map +1 -1
  38. package/dist/sdk/index.cjs +18 -6
  39. package/dist/sdk/index.cjs.map +1 -1
  40. package/dist/sdk/index.mjs +18 -6
  41. package/dist/sdk/index.mjs.map +1 -1
  42. package/dist/server/index.d.ts +1 -0
  43. package/dist/server/index.d.ts.map +1 -1
  44. package/dist/server/index.mjs +23 -9
  45. package/dist/server/index.mjs.map +1 -1
  46. package/dist/svelte/index.cjs +2 -1
  47. package/dist/svelte/index.cjs.map +1 -1
  48. package/dist/svelte/index.mjs +2 -1
  49. package/dist/svelte/index.mjs.map +1 -1
  50. package/dist/tanstack/index.cjs +2 -1
  51. package/dist/tanstack/index.cjs.map +1 -1
  52. package/dist/tanstack/index.mjs +2 -1
  53. package/dist/tanstack/index.mjs.map +1 -1
  54. package/dist/vue/index.cjs +2 -1
  55. package/dist/vue/index.cjs.map +1 -1
  56. package/dist/vue/index.mjs +2 -1
  57. package/dist/vue/index.mjs.map +1 -1
  58. package/package.json +1 -1
  59. package/src/lib/algebraic_type.ts +5 -1
  60. package/src/lib/query.ts +60 -19
  61. package/src/lib/table.ts +6 -1
  62. package/src/react/useTable.ts +5 -0
  63. package/src/server/index.ts +1 -0
  64. package/src/server/view.test-d.ts +4 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spacetimedb",
3
- "version": "2.0.4",
3
+ "version": "2.1.0",
4
4
  "description": "API and ABI bindings for the SpacetimeDB TypeScript module library",
5
5
  "homepage": "https://github.com/clockworklabs/SpacetimeDB#readme",
6
6
  "bugs": {
@@ -535,7 +535,11 @@ const view = reader.view;
535
535
  ${ty.elements
536
536
  .map(({ name, algebraicType: { tag } }) =>
537
537
  tag in primitiveJSName
538
- ? `\
538
+ ? tag === 'Bool'
539
+ ? `\
540
+ result.${name} = view.getUint8(reader.offset) !== 0;
541
+ reader.offset += 1;`
542
+ : `\
539
543
  result.${name} = view.get${primitiveJSName[tag as JSPrimitives]}(reader.offset, ${primitiveSizes[tag] > 1 ? 'true' : ''});
540
544
  reader.offset += ${primitiveSizes[tag]};`
541
545
  : `result.${name} = reader.read${tag}();`
package/src/lib/query.ts CHANGED
@@ -348,7 +348,8 @@ function createRowExpr<TableDef extends TypedTableDef>(
348
348
  columnBuilder.typeBuilder.algebraicType as InferSpacetimeTypeOfColumn<
349
349
  TableDef,
350
350
  typeof columnName
351
- >
351
+ >,
352
+ columnBuilder.columnMetadata.name
352
353
  );
353
354
  row[columnName] = Object.freeze(column);
354
355
  }
@@ -438,7 +439,10 @@ export class ColumnExpression<
438
439
  ColumnName extends ColumnNames<TableDef>,
439
440
  > {
440
441
  readonly type = 'column' as const;
442
+ // This is the column accessor
441
443
  readonly column: ColumnName;
444
+ // The name of the column in the database.
445
+ readonly columnName: string;
442
446
  readonly table: TableDef['sourceName'];
443
447
  // phantom: actual runtime value is undefined
444
448
  readonly tsValueType?: RowType<TableDef>[ColumnName];
@@ -447,10 +451,12 @@ export class ColumnExpression<
447
451
  constructor(
448
452
  table: TableDef['sourceName'],
449
453
  column: ColumnName,
450
- spacetimeType: InferSpacetimeTypeOfColumn<TableDef, ColumnName>
454
+ spacetimeType: InferSpacetimeTypeOfColumn<TableDef, ColumnName>,
455
+ columnName?: string
451
456
  ) {
452
457
  this.table = table;
453
458
  this.column = column;
459
+ this.columnName = columnName || column;
454
460
  this.spacetimeType = spacetimeType;
455
461
  }
456
462
 
@@ -710,15 +716,38 @@ type BooleanExprData<Table extends TypedTableDef> = (
710
716
  _tableType?: Table;
711
717
  };
712
718
 
719
+ type AndOrMixedTableScopeError = {
720
+ readonly 'Cannot combine predicates from different table scopes with and/or. In semijoin on(...), keep only the join equality and move extra predicates to .where(...).': never;
721
+ };
722
+
723
+ type RequireSameAndOrTable<
724
+ Expected extends TypedTableDef,
725
+ Actual extends TypedTableDef,
726
+ > = [Expected] extends [Actual]
727
+ ? [Actual] extends [Expected]
728
+ ? unknown
729
+ : AndOrMixedTableScopeError
730
+ : AndOrMixedTableScopeError;
731
+
713
732
  export class BooleanExpr<Table extends TypedTableDef> {
714
733
  constructor(readonly data: BooleanExprData<Table>) {}
715
734
 
716
- and(other: BooleanExpr<Table>): BooleanExpr<Table> {
717
- return new BooleanExpr({ type: 'and', clauses: [this.data, other.data] });
735
+ and<OtherTable extends TypedTableDef>(
736
+ other: BooleanExpr<OtherTable> & RequireSameAndOrTable<Table, OtherTable>
737
+ ): BooleanExpr<Table> {
738
+ return new BooleanExpr({
739
+ type: 'and',
740
+ clauses: [this.data, other.data as BooleanExprData<Table>],
741
+ });
718
742
  }
719
743
 
720
- or(other: BooleanExpr<Table>): BooleanExpr<Table> {
721
- return new BooleanExpr({ type: 'or', clauses: [this.data, other.data] });
744
+ or<OtherTable extends TypedTableDef>(
745
+ other: BooleanExpr<OtherTable> & RequireSameAndOrTable<Table, OtherTable>
746
+ ): BooleanExpr<Table> {
747
+ return new BooleanExpr({
748
+ type: 'or',
749
+ clauses: [this.data, other.data as BooleanExprData<Table>],
750
+ });
722
751
  }
723
752
 
724
753
  not(): BooleanExpr<Table> {
@@ -732,28 +761,40 @@ export function not<T extends TypedTableDef>(
732
761
  return new BooleanExpr({ type: 'not', clause: clause.data });
733
762
  }
734
763
 
735
- export function and<T extends TypedTableDef>(
736
- ...clauses: readonly [BooleanExpr<T>, BooleanExpr<T>, ...BooleanExpr<T>[]]
737
- ): BooleanExpr<T> {
764
+ export function and<
765
+ Table extends TypedTableDef,
766
+ OtherTable extends TypedTableDef,
767
+ >(
768
+ first: BooleanExpr<Table>,
769
+ second: BooleanExpr<OtherTable> & RequireSameAndOrTable<Table, OtherTable>,
770
+ ...rest: readonly BooleanExpr<Table>[]
771
+ ): BooleanExpr<Table> {
772
+ const clauses = [first, second, ...rest];
738
773
  return new BooleanExpr({
739
774
  type: 'and',
740
775
  clauses: clauses.map(c => c.data) as [
741
- BooleanExprData<T>,
742
- BooleanExprData<T>,
743
- ...BooleanExprData<T>[],
776
+ BooleanExprData<Table>,
777
+ BooleanExprData<Table>,
778
+ ...BooleanExprData<Table>[],
744
779
  ],
745
780
  });
746
781
  }
747
782
 
748
- export function or<T extends TypedTableDef>(
749
- ...clauses: readonly [BooleanExpr<T>, BooleanExpr<T>, ...BooleanExpr<T>[]]
750
- ): BooleanExpr<T> {
783
+ export function or<
784
+ Table extends TypedTableDef,
785
+ OtherTable extends TypedTableDef,
786
+ >(
787
+ first: BooleanExpr<Table>,
788
+ second: BooleanExpr<OtherTable> & RequireSameAndOrTable<Table, OtherTable>,
789
+ ...rest: readonly BooleanExpr<Table>[]
790
+ ): BooleanExpr<Table> {
791
+ const clauses = [first, second, ...rest];
751
792
  return new BooleanExpr({
752
793
  type: 'or',
753
794
  clauses: clauses.map(c => c.data) as [
754
- BooleanExprData<T>,
755
- BooleanExprData<T>,
756
- ...BooleanExprData<T>[],
795
+ BooleanExprData<Table>,
796
+ BooleanExprData<Table>,
797
+ ...BooleanExprData<Table>[],
757
798
  ],
758
799
  });
759
800
  }
@@ -803,7 +844,7 @@ function valueExprToSql<Table extends TypedTableDef>(
803
844
  return literalValueToSql(expr.value);
804
845
  }
805
846
  const table = tableAlias ?? expr.table;
806
- return `${quoteIdentifier(table)}.${quoteIdentifier(expr.column)}`;
847
+ return `${quoteIdentifier(table)}.${quoteIdentifier(expr.columnName)}`;
807
848
  }
808
849
 
809
850
  function literalValueToSql(value: unknown): string {
package/src/lib/table.ts CHANGED
@@ -239,7 +239,12 @@ export type ReadonlyTable<TableDef extends UntypedTableDef> = Prettify<
239
239
  >;
240
240
 
241
241
  export interface ReadonlyTableMethods<TableDef extends UntypedTableDef> {
242
- /** Returns the number of rows in the TX state. */
242
+ /**
243
+ * Returns the number of rows in this table.
244
+ *
245
+ * This reads datastore metadata, so it runs in constant time.
246
+ * It also takes into account modifications by the current transaction.
247
+ */
243
248
  count(): bigint;
244
249
 
245
250
  /** Iterate over all rows in the TX state. Rust Iterator<Item=Row> → TS IterableIterator<Row>. */
@@ -104,6 +104,8 @@ export function useTable<TableDef extends UntypedTableDef>(
104
104
  ) as Prettify<UseTableRowType>[])
105
105
  : (Array.from(table.iter()) as Prettify<UseTableRowType>[]);
106
106
  return [result, subscribeApplied];
107
+ // TODO: investigating refactoring so that this is no longer necessary, as we have had genuine bugs with missed deps.
108
+ // See https://github.com/clockworklabs/SpacetimeDB/pull/4580.
107
109
  // eslint-disable-next-line react-hooks/exhaustive-deps
108
110
  }, [connectionState, accessorName, querySql, subscribeApplied]);
109
111
 
@@ -205,11 +207,14 @@ export function useTable<TableDef extends UntypedTableDef>(
205
207
  table.removeOnUpdate?.(onUpdate);
206
208
  };
207
209
  },
210
+ // TODO: investigating refactoring so that this is no longer necessary, as we have had genuine bugs with missed deps.
211
+ // See https://github.com/clockworklabs/SpacetimeDB/pull/4580.
208
212
  // eslint-disable-next-line react-hooks/exhaustive-deps
209
213
  [
210
214
  connectionState,
211
215
  accessorName,
212
216
  querySql,
217
+ computeSnapshot,
213
218
  callbacks?.onDelete,
214
219
  callbacks?.onInsert,
215
220
  callbacks?.onUpdate,
@@ -21,5 +21,6 @@ export { toCamelCase } from '../lib/util';
21
21
  export type { Uuid } from '../lib/uuid';
22
22
  export type { Random } from './rng';
23
23
  export type { ViewExport, ViewCtx, AnonymousViewCtx } from './views';
24
+ export { Range, type Bound } from './range';
24
25
 
25
26
  import './polyfills'; // Ensure polyfills are loaded
@@ -161,6 +161,10 @@ spacetime.anonymousView({ name: 'v5', public: true }, arrayRetValue, ctx => {
161
161
  .where(row => row.id.eq(5))
162
162
  .leftSemijoin(ctx.from.order, (p, o) => p.name.eq(o.person_name))
163
163
  .build();
164
+ const _mixedScopeAndInJoinPredicate = ctx.from.person
165
+ // @ts-expect-error semijoin on(...) only supports one table scope for and/or clauses.
166
+ .leftSemijoin(ctx.from.order, (p, o) => p.id.eq(o.id).and(o.id.eq(5)))
167
+ .build();
164
168
  return ctx.from.person
165
169
  .where(row => row.id.eq(5))
166
170
  .leftSemijoin(ctx.from.order, (p, o) => p.id.eq(o.id))