spacetimedb 2.0.3 → 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 (88) hide show
  1. package/LICENSE.txt +2 -2
  2. package/dist/angular/index.cjs +5 -1
  3. package/dist/angular/index.cjs.map +1 -1
  4. package/dist/angular/index.mjs +5 -1
  5. package/dist/angular/index.mjs.map +1 -1
  6. package/dist/browser/angular/index.mjs +5 -1
  7. package/dist/browser/angular/index.mjs.map +1 -1
  8. package/dist/browser/react/index.mjs +8 -1
  9. package/dist/browser/react/index.mjs.map +1 -1
  10. package/dist/browser/svelte/index.mjs +5 -1
  11. package/dist/browser/svelte/index.mjs.map +1 -1
  12. package/dist/browser/vue/index.mjs +5 -1
  13. package/dist/browser/vue/index.mjs.map +1 -1
  14. package/dist/index.browser.mjs +148 -100
  15. package/dist/index.browser.mjs.map +1 -1
  16. package/dist/index.cjs +148 -100
  17. package/dist/index.cjs.map +1 -1
  18. package/dist/index.mjs +148 -100
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/lib/algebraic_type.d.ts.map +1 -1
  21. package/dist/lib/binary_writer.d.ts +1 -0
  22. package/dist/lib/binary_writer.d.ts.map +1 -1
  23. package/dist/lib/indexes.d.ts +1 -1
  24. package/dist/lib/indexes.d.ts.map +1 -1
  25. package/dist/lib/query.d.ts +14 -7
  26. package/dist/lib/query.d.ts.map +1 -1
  27. package/dist/lib/schema.d.ts +2 -0
  28. package/dist/lib/schema.d.ts.map +1 -1
  29. package/dist/lib/table.d.ts +25 -2
  30. package/dist/lib/table.d.ts.map +1 -1
  31. package/dist/min/index.browser.mjs +1 -1
  32. package/dist/min/index.browser.mjs.map +1 -1
  33. package/dist/min/react/index.mjs +1 -1
  34. package/dist/min/react/index.mjs.map +1 -1
  35. package/dist/min/sdk/index.browser.mjs +1 -1
  36. package/dist/min/sdk/index.browser.mjs.map +1 -1
  37. package/dist/react/index.cjs +8 -1
  38. package/dist/react/index.cjs.map +1 -1
  39. package/dist/react/index.mjs +8 -1
  40. package/dist/react/index.mjs.map +1 -1
  41. package/dist/react/useTable.d.ts.map +1 -1
  42. package/dist/sdk/db_connection_impl.d.ts.map +1 -1
  43. package/dist/sdk/index.browser.mjs +144 -98
  44. package/dist/sdk/index.browser.mjs.map +1 -1
  45. package/dist/sdk/index.cjs +144 -98
  46. package/dist/sdk/index.cjs.map +1 -1
  47. package/dist/sdk/index.mjs +144 -98
  48. package/dist/sdk/index.mjs.map +1 -1
  49. package/dist/sdk/table_cache.d.ts.map +1 -1
  50. package/dist/sdk/websocket_decompress_adapter.d.ts +17 -7
  51. package/dist/sdk/websocket_decompress_adapter.d.ts.map +1 -1
  52. package/dist/sdk/websocket_test_adapter.d.ts +3 -2
  53. package/dist/sdk/websocket_test_adapter.d.ts.map +1 -1
  54. package/dist/server/index.d.ts +1 -0
  55. package/dist/server/index.d.ts.map +1 -1
  56. package/dist/server/index.mjs +88 -30
  57. package/dist/server/index.mjs.map +1 -1
  58. package/dist/svelte/index.cjs +5 -1
  59. package/dist/svelte/index.cjs.map +1 -1
  60. package/dist/svelte/index.mjs +5 -1
  61. package/dist/svelte/index.mjs.map +1 -1
  62. package/dist/tanstack/SpacetimeDBQueryClient.d.ts +1 -0
  63. package/dist/tanstack/SpacetimeDBQueryClient.d.ts.map +1 -1
  64. package/dist/tanstack/index.cjs +26 -1
  65. package/dist/tanstack/index.cjs.map +1 -1
  66. package/dist/tanstack/index.mjs +26 -1
  67. package/dist/tanstack/index.mjs.map +1 -1
  68. package/dist/vue/index.cjs +5 -1
  69. package/dist/vue/index.cjs.map +1 -1
  70. package/dist/vue/index.mjs +5 -1
  71. package/dist/vue/index.mjs.map +1 -1
  72. package/package.json +1 -1
  73. package/src/lib/algebraic_type.ts +5 -1
  74. package/src/lib/binary_writer.ts +4 -0
  75. package/src/lib/indexes.ts +1 -1
  76. package/src/lib/query.ts +90 -25
  77. package/src/lib/schema.ts +66 -24
  78. package/src/lib/table.ts +47 -10
  79. package/src/react/useTable.ts +5 -0
  80. package/src/sdk/db_connection_impl.ts +38 -43
  81. package/src/sdk/table_cache.ts +14 -11
  82. package/src/sdk/websocket_decompress_adapter.ts +42 -45
  83. package/src/sdk/websocket_test_adapter.ts +3 -2
  84. package/src/server/index.ts +1 -0
  85. package/src/server/runtime.ts +7 -3
  86. package/src/server/schema.test-d.ts +37 -0
  87. package/src/server/view.test-d.ts +6 -0
  88. package/src/tanstack/SpacetimeDBQueryClient.ts +24 -0
@@ -581,6 +581,9 @@ var BinaryWriter = class {
581
581
  constructor(init) {
582
582
  this.buffer = typeof init === "number" ? new ResizableBuffer(init) : init;
583
583
  }
584
+ clear() {
585
+ this.offset = 0;
586
+ }
584
587
  reset(buffer) {
585
588
  this.buffer = buffer;
586
589
  this.offset = 0;
@@ -1220,7 +1223,8 @@ writer.offset += ${primitiveSizes[tag]};` : `writer.write${tag}(value.${name});`
1220
1223
  const result = { ${ty.elements.map(getElementInitializer).join(", ")} };
1221
1224
  const view = reader.view;
1222
1225
  ${ty.elements.map(
1223
- ({ name, algebraicType: { tag } }) => tag in primitiveJSName ? `result.${name} = view.get${primitiveJSName[tag]}(reader.offset, ${primitiveSizes[tag] > 1 ? "true" : ""});
1226
+ ({ name, algebraicType: { tag } }) => tag in primitiveJSName ? tag === "Bool" ? `result.${name} = view.getUint8(reader.offset) !== 0;
1227
+ reader.offset += 1;` : `result.${name} = view.get${primitiveJSName[tag]}(reader.offset, ${primitiveSizes[tag] > 1 ? "true" : ""});
1224
1228
  reader.offset += ${primitiveSizes[tag]};` : `result.${name} = reader.read${tag}();`
1225
1229
  ).join("\n")}
1226
1230
  return result;`;
@@ -1628,7 +1632,7 @@ var FromBuilder = class _FromBuilder {
1628
1632
  }
1629
1633
  [QueryBrand] = true;
1630
1634
  where(predicate) {
1631
- const newCondition = predicate(this.table.cols);
1635
+ const newCondition = normalizePredicateExpr(predicate(this.table.cols));
1632
1636
  const nextWhere = this.whereClause ? this.whereClause.and(newCondition) : newCondition;
1633
1637
  return new _FromBuilder(this.table, nextWhere);
1634
1638
  }
@@ -1723,7 +1727,8 @@ function createRowExpr(tableDef) {
1723
1727
  const column = new ColumnExpression(
1724
1728
  tableDef.sourceName,
1725
1729
  columnName,
1726
- columnBuilder.typeBuilder.algebraicType
1730
+ columnBuilder.typeBuilder.algebraicType,
1731
+ columnBuilder.columnMetadata.name
1727
1732
  );
1728
1733
  row[columnName] = Object.freeze(column);
1729
1734
  }
@@ -1741,14 +1746,18 @@ function renderSelectSqlWithJoins(table2, where, extraClauses = []) {
1741
1746
  }
1742
1747
  var ColumnExpression = class {
1743
1748
  type = "column";
1749
+ // This is the column accessor
1744
1750
  column;
1751
+ // The name of the column in the database.
1752
+ columnName;
1745
1753
  table;
1746
1754
  // phantom: actual runtime value is undefined
1747
1755
  tsValueType;
1748
1756
  spacetimeType;
1749
- constructor(table2, column, spacetimeType) {
1757
+ constructor(table2, column, spacetimeType, columnName) {
1750
1758
  this.table = table2;
1751
1759
  this.column = column;
1760
+ this.columnName = columnName || column;
1752
1761
  this.spacetimeType = spacetimeType;
1753
1762
  }
1754
1763
  eq(x) {
@@ -1805,15 +1814,36 @@ function normalizeValue(val) {
1805
1814
  }
1806
1815
  return literal(val);
1807
1816
  }
1817
+ function normalizePredicateExpr(value) {
1818
+ if (value instanceof BooleanExpr) return value;
1819
+ if (typeof value === "boolean") {
1820
+ return new BooleanExpr({
1821
+ type: "eq",
1822
+ left: literal(value),
1823
+ right: literal(true)
1824
+ });
1825
+ }
1826
+ return new BooleanExpr({
1827
+ type: "eq",
1828
+ left: value,
1829
+ right: literal(true)
1830
+ });
1831
+ }
1808
1832
  var BooleanExpr = class _BooleanExpr {
1809
1833
  constructor(data) {
1810
1834
  this.data = data;
1811
1835
  }
1812
1836
  and(other) {
1813
- return new _BooleanExpr({ type: "and", clauses: [this.data, other.data] });
1837
+ return new _BooleanExpr({
1838
+ type: "and",
1839
+ clauses: [this.data, other.data]
1840
+ });
1814
1841
  }
1815
1842
  or(other) {
1816
- return new _BooleanExpr({ type: "or", clauses: [this.data, other.data] });
1843
+ return new _BooleanExpr({
1844
+ type: "or",
1845
+ clauses: [this.data, other.data]
1846
+ });
1817
1847
  }
1818
1848
  not() {
1819
1849
  return new _BooleanExpr({ type: "not", clause: this.data });
@@ -1822,13 +1852,15 @@ var BooleanExpr = class _BooleanExpr {
1822
1852
  function not(clause) {
1823
1853
  return new BooleanExpr({ type: "not", clause: clause.data });
1824
1854
  }
1825
- function and(...clauses) {
1855
+ function and(first, second, ...rest) {
1856
+ const clauses = [first, second, ...rest];
1826
1857
  return new BooleanExpr({
1827
1858
  type: "and",
1828
1859
  clauses: clauses.map((c) => c.data)
1829
1860
  });
1830
1861
  }
1831
- function or(...clauses) {
1862
+ function or(first, second, ...rest) {
1863
+ const clauses = [first, second, ...rest];
1832
1864
  return new BooleanExpr({
1833
1865
  type: "or",
1834
1866
  clauses: clauses.map((c) => c.data)
@@ -1865,7 +1897,7 @@ function valueExprToSql(expr, tableAlias) {
1865
1897
  return literalValueToSql(expr.value);
1866
1898
  }
1867
1899
  const table2 = expr.table;
1868
- return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.column)}`;
1900
+ return `${quoteIdentifier(table2)}.${quoteIdentifier(expr.columnName)}`;
1869
1901
  }
1870
1902
  function literalValueToSql(value) {
1871
1903
  if (value === null || value === void 0) {
@@ -4446,9 +4478,7 @@ var TableCacheImpl = class {
4446
4478
  this.tableDef = tableDef;
4447
4479
  this.rows = /* @__PURE__ */ new Map();
4448
4480
  this.emitter = new EventEmitter();
4449
- const indexesDef = this.tableDef.indexes || [];
4450
- for (const idx of indexesDef) {
4451
- const idxDef = idx;
4481
+ for (const idxDef of this.tableDef.resolvedIndexes) {
4452
4482
  const index = this.#makeReadonlyIndex(this.tableDef, idxDef);
4453
4483
  this[idxDef.name] = index;
4454
4484
  }
@@ -5005,37 +5035,39 @@ async function resolveWS() {
5005
5035
 
5006
5036
  // src/sdk/websocket_decompress_adapter.ts
5007
5037
  var WebsocketDecompressAdapter = class _WebsocketDecompressAdapter {
5008
- onclose;
5009
- onopen;
5010
- onmessage;
5011
- onerror;
5012
- #ws;
5013
- async #handleOnMessage(msg) {
5014
- const buffer = new Uint8Array(msg.data);
5015
- let decompressed;
5016
- if (buffer[0] === 0) {
5017
- decompressed = buffer.slice(1);
5018
- } else if (buffer[0] === 1) {
5019
- throw new Error(
5020
- "Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection."
5021
- );
5022
- } else if (buffer[0] === 2) {
5023
- decompressed = await decompress(buffer.slice(1), "gzip");
5024
- } else {
5025
- throw new Error(
5026
- "Unexpected Compression Algorithm. Please use `gzip` or `none`"
5027
- );
5028
- }
5029
- this.onmessage?.({ data: decompressed });
5038
+ set onclose(handler) {
5039
+ this.#ws.onclose = handler;
5030
5040
  }
5031
- #handleOnOpen(msg) {
5032
- this.onopen?.(msg);
5041
+ set onopen(handler) {
5042
+ this.#ws.onopen = handler;
5033
5043
  }
5034
- #handleOnError(msg) {
5035
- this.onerror?.(msg);
5044
+ set onmessage(handler) {
5045
+ this.#ws.onmessage = async (msg) => {
5046
+ const data = await this.#decompress(new Uint8Array(msg.data));
5047
+ handler({ data });
5048
+ };
5036
5049
  }
5037
- #handleOnClose(msg) {
5038
- this.onclose?.(msg);
5050
+ set onerror(handler) {
5051
+ this.#ws.onerror = handler;
5052
+ }
5053
+ #ws;
5054
+ async #decompress(buffer) {
5055
+ const tag = buffer[0];
5056
+ const data = buffer.subarray(1);
5057
+ switch (tag) {
5058
+ case 0:
5059
+ return data;
5060
+ case 1:
5061
+ throw new Error(
5062
+ "Brotli Compression not supported. Please use gzip or none compression in withCompression method on DbConnection."
5063
+ );
5064
+ case 2:
5065
+ return await decompress(data, "gzip");
5066
+ default:
5067
+ throw new Error(
5068
+ "Unexpected Compression Algorithm. Please use `gzip` or `none`"
5069
+ );
5070
+ }
5039
5071
  }
5040
5072
  send(msg) {
5041
5073
  this.#ws.send(msg);
@@ -5044,14 +5076,6 @@ var WebsocketDecompressAdapter = class _WebsocketDecompressAdapter {
5044
5076
  this.#ws.close();
5045
5077
  }
5046
5078
  constructor(ws) {
5047
- this.onmessage = void 0;
5048
- this.onopen = void 0;
5049
- this.onmessage = void 0;
5050
- this.onerror = void 0;
5051
- ws.onmessage = this.#handleOnMessage.bind(this);
5052
- ws.onerror = this.#handleOnError.bind(this);
5053
- ws.onclose = this.#handleOnClose.bind(this);
5054
- ws.onopen = this.#handleOnOpen.bind(this);
5055
5079
  ws.binaryType = "arraybuffer";
5056
5080
  this.#ws = ws;
5057
5081
  }
@@ -5688,12 +5712,13 @@ var DbConnectionImpl = class {
5688
5712
  }
5689
5713
  #makeReducers(def) {
5690
5714
  const out = {};
5715
+ const writer = new BinaryWriter(1024);
5691
5716
  for (const reducer of def.reducers) {
5692
5717
  const reducerName = reducer.name;
5693
5718
  const key = reducer.accessorName;
5694
5719
  const { serialize: serializeArgs } = this.#reducerArgsSerializers[reducerName];
5695
5720
  out[key] = (params) => {
5696
- const writer = new BinaryWriter(1024);
5721
+ writer.clear();
5697
5722
  serializeArgs(writer, params);
5698
5723
  const argsBuffer = writer.getBuffer();
5699
5724
  return this.callReducer(reducerName, argsBuffer, params);
@@ -5703,12 +5728,13 @@ var DbConnectionImpl = class {
5703
5728
  }
5704
5729
  #makeProcedures(def) {
5705
5730
  const out = {};
5731
+ const writer = new BinaryWriter(1024);
5706
5732
  for (const procedure of def.procedures) {
5707
5733
  const procedureName = procedure.name;
5708
5734
  const key = procedure.accessorName;
5709
5735
  const { serializeArgs, deserializeReturn } = this.#procedureSerializers[procedureName];
5710
5736
  out[key] = (params) => {
5711
- const writer = new BinaryWriter(1024);
5737
+ writer.clear();
5712
5738
  serializeArgs(writer, params);
5713
5739
  const argsBuffer = writer.getBuffer();
5714
5740
  return this.callProcedure(procedureName, argsBuffer).then((returnBuf) => {
@@ -5863,34 +5889,32 @@ var DbConnectionImpl = class {
5863
5889
  }
5864
5890
  return this.#mergeTableUpdates(updates);
5865
5891
  }
5866
- #sendEncoded(wsResolved, message) {
5867
- stdbLogger(
5868
- "trace",
5869
- () => `Sending message to server: ${stringify(message)}`
5870
- );
5871
- const writer = new BinaryWriter(1024);
5872
- ClientMessage.serialize(writer, message);
5873
- const encoded = writer.getBuffer();
5874
- wsResolved.send(encoded);
5875
- }
5876
5892
  #flushOutboundQueue(wsResolved) {
5877
- if (!this.isActive || this.#outboundQueue.length === 0) {
5878
- return;
5879
- }
5880
5893
  const pending = this.#outboundQueue.splice(0);
5881
5894
  for (const message of pending) {
5882
- this.#sendEncoded(wsResolved, message);
5895
+ wsResolved.send(message);
5883
5896
  }
5884
5897
  }
5898
+ #clientMessageEncoder = new BinaryWriter(1024);
5885
5899
  #sendMessage(message) {
5886
- this.wsPromise.then((wsResolved) => {
5887
- if (!wsResolved || !this.isActive) {
5888
- this.#outboundQueue.push(message);
5889
- return;
5890
- }
5891
- this.#flushOutboundQueue(wsResolved);
5892
- this.#sendEncoded(wsResolved, message);
5893
- });
5900
+ const writer = this.#clientMessageEncoder;
5901
+ writer.clear();
5902
+ ClientMessage.serialize(writer, message);
5903
+ const encoded = writer.getBuffer();
5904
+ if (this.ws && this.isActive) {
5905
+ if (this.#outboundQueue.length) this.#flushOutboundQueue(this.ws);
5906
+ stdbLogger(
5907
+ "trace",
5908
+ () => `Sending message to server: ${stringify(message)}`
5909
+ );
5910
+ this.ws.send(encoded);
5911
+ } else {
5912
+ stdbLogger(
5913
+ "trace",
5914
+ () => `Queuing message to server: ${stringify(message)}`
5915
+ );
5916
+ this.#outboundQueue.push(encoded.slice());
5917
+ }
5894
5918
  }
5895
5919
  #nextEventId() {
5896
5920
  this.#eventId += 1;
@@ -6232,11 +6256,7 @@ var DbConnectionImpl = class {
6232
6256
  * ```
6233
6257
  */
6234
6258
  disconnect() {
6235
- this.wsPromise.then((wsResolved) => {
6236
- if (wsResolved) {
6237
- wsResolved.close();
6238
- }
6239
- });
6259
+ this.wsPromise.then((ws) => ws?.close());
6240
6260
  }
6241
6261
  on(eventName, callback) {
6242
6262
  this.#emitter.on(eventName, callback);
@@ -6266,17 +6286,45 @@ var DbConnectionImpl = class {
6266
6286
 
6267
6287
  // src/lib/schema.ts
6268
6288
  function tablesToSchema(ctx, tables) {
6289
+ const tableDefs = /* @__PURE__ */ Object.create(null);
6290
+ for (const [accName, schema2] of Object.entries(tables)) {
6291
+ tableDefs[accName] = tableToSchema(
6292
+ accName,
6293
+ schema2,
6294
+ schema2.tableDef(ctx, accName)
6295
+ );
6296
+ }
6269
6297
  return {
6270
- tables: Object.fromEntries(
6271
- Object.entries(tables).map(([accName, schema2]) => [
6272
- accName,
6273
- tableToSchema(accName, schema2, schema2.tableDef(ctx, accName))
6274
- ])
6275
- )
6298
+ tables: tableDefs
6276
6299
  };
6277
6300
  }
6278
6301
  function tableToSchema(accName, schema2, tableDef) {
6279
6302
  const getColName = (i) => schema2.rowType.algebraicType.value.elements[i].name;
6303
+ const resolvedIndexes = tableDef.indexes.map(
6304
+ (idx) => {
6305
+ const accessorName = idx.accessorName;
6306
+ if (typeof accessorName !== "string" || accessorName.length === 0) {
6307
+ throw new TypeError(
6308
+ `Index '${idx.sourceName ?? "<unknown>"}' on table '${tableDef.sourceName}' is missing accessor name`
6309
+ );
6310
+ }
6311
+ const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value;
6312
+ const unique = tableDef.constraints.some(
6313
+ (c) => c.data.tag === "Unique" && c.data.value.columns.every((col) => columnIds.includes(col))
6314
+ );
6315
+ const algorithm = {
6316
+ BTree: "btree",
6317
+ Hash: "hash",
6318
+ Direct: "direct"
6319
+ }[idx.algorithm.tag];
6320
+ return {
6321
+ name: accessorName,
6322
+ unique,
6323
+ algorithm,
6324
+ columns: columnIds.map(getColName)
6325
+ };
6326
+ }
6327
+ );
6280
6328
  return {
6281
6329
  // For client,`schama.tableName` will always be there as canonical name.
6282
6330
  // For module, if explicit name is not provided via `name`, accessor name will
@@ -6286,26 +6334,16 @@ function tableToSchema(accName, schema2, tableDef) {
6286
6334
  columns: schema2.rowType.row,
6287
6335
  // typed as T[i]['rowType']['row'] under TablesToSchema<T>
6288
6336
  rowType: schema2.rowSpacetimeType,
6337
+ // Keep declarative indexes in their original shape for type-level consumers.
6338
+ indexes: schema2.idxs,
6289
6339
  constraints: tableDef.constraints.map((c) => ({
6290
6340
  name: c.sourceName,
6291
6341
  constraint: "unique",
6292
6342
  columns: c.data.value.columns.map(getColName)
6293
6343
  })),
6294
- // TODO: horrible horrible horrible. we smuggle this `Array<UntypedIndex>`
6295
- // by casting it to an `Array<IndexOpts>` as `TableToSchema` expects.
6296
- // This is then used in `TableCacheImpl.constructor` and who knows where else.
6297
- // We should stop lying about our types.
6298
- indexes: tableDef.indexes.map((idx) => {
6299
- const columnIds = idx.algorithm.tag === "Direct" ? [idx.algorithm.value] : idx.algorithm.value;
6300
- return {
6301
- name: idx.accessorName,
6302
- unique: tableDef.constraints.some(
6303
- (c) => c.data.value.columns.every((col) => columnIds.includes(col))
6304
- ),
6305
- algorithm: idx.algorithm.tag.toLowerCase(),
6306
- columns: columnIds.map(getColName)
6307
- };
6308
- }),
6344
+ // Expose resolved runtime indexes separately so runtime users don't have to
6345
+ // reinterpret `indexes` with unsafe casts.
6346
+ resolvedIndexes,
6309
6347
  tableDef,
6310
6348
  ...tableDef.isEvent ? { isEvent: true } : {}
6311
6349
  };
@@ -7129,6 +7167,14 @@ function table(opts, row, ..._) {
7129
7167
  }
7130
7168
  }
7131
7169
  for (const indexOpts of userIndexes ?? []) {
7170
+ const accessor = indexOpts.accessor;
7171
+ if (typeof accessor !== "string" || accessor.length === 0) {
7172
+ const tableLabel = name ?? "<unnamed>";
7173
+ const indexLabel = indexOpts.name ?? "<unnamed>";
7174
+ throw new TypeError(
7175
+ `Index '${indexLabel}' on table '${tableLabel}' must define a non-empty 'accessor'`
7176
+ );
7177
+ }
7132
7178
  let algorithm;
7133
7179
  switch (indexOpts.algorithm) {
7134
7180
  case "btree":
@@ -7149,7 +7195,7 @@ function table(opts, row, ..._) {
7149
7195
  }
7150
7196
  indexes.push({
7151
7197
  sourceName: void 0,
7152
- accessorName: indexOpts.accessor,
7198
+ accessorName: accessor,
7153
7199
  algorithm,
7154
7200
  canonicalName: indexOpts.name
7155
7201
  });
@@ -7199,7 +7245,9 @@ function table(opts, row, ..._) {
7199
7245
  isEvent
7200
7246
  };
7201
7247
  },
7202
- idxs: {},
7248
+ // Preserve the declared index options as runtime data so `tableToSchema`
7249
+ // can expose them without type-smuggling.
7250
+ idxs: userIndexes,
7203
7251
  constraints,
7204
7252
  schedule
7205
7253
  };